zahiraam updated this revision to Diff 433104. Herald added a subscriber: jsji.
CHANGES SINCE LAST ACTION https://reviews.llvm.org/D113107/new/ https://reviews.llvm.org/D113107 Files: clang/docs/LanguageExtensions.rst clang/docs/ReleaseNotes.rst clang/include/clang/Basic/TargetInfo.h clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/CodeGen/CGExprScalar.cpp clang/test/CodeGen/X86/Float16-arithmetic.c clang/test/CodeGen/X86/Float16-complex.c clang/test/CodeGen/X86/avx512fp16-complex.c clang/test/Sema/Float16.c clang/test/Sema/conversion-target-dep.c clang/test/SemaCXX/Float16.cpp
Index: clang/test/SemaCXX/Float16.cpp =================================================================== --- clang/test/SemaCXX/Float16.cpp +++ clang/test/SemaCXX/Float16.cpp @@ -1,18 +1,10 @@ // RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc %s -// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s -DHAVE -// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s -DHAVE -// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s -DHAVE +// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s -#ifdef HAVE // expected-no-diagnostics -#endif // HAVE -#ifndef HAVE -// expected-error@+2{{_Float16 is not supported on this target}} -#endif // !HAVE _Float16 f; -#ifndef HAVE -// expected-error@+2{{invalid suffix 'F16' on floating constant}} -#endif // !HAVE const auto g = 1.1F16; Index: clang/test/Sema/conversion-target-dep.c =================================================================== --- clang/test/Sema/conversion-target-dep.c +++ clang/test/Sema/conversion-target-dep.c @@ -6,7 +6,7 @@ long double ld; double d; -_Float16 f16; // x86-error {{_Float16 is not supported on this target}} +_Float16 f16; int main(void) { ld = d; // x86-warning {{implicit conversion increases floating-point precision: 'double' to 'long double'}} Index: clang/test/Sema/Float16.c =================================================================== --- clang/test/Sema/Float16.c +++ clang/test/Sema/Float16.c @@ -1,18 +1,12 @@ // RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc %s -// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc -target-feature +avx512fp16 %s -DHAVE -// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s -DHAVE -// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s -DHAVE -// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s -DHAVE +// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc -target-feature +avx512fp16 %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s -#ifndef HAVE -// expected-error@+2{{_Float16 is not supported on this target}} -#endif // HAVE -_Float16 f; - -#ifdef HAVE _Complex _Float16 a; void builtin_complex(void) { _Float16 a = 0; (void)__builtin_complex(a, a); // expected-error {{'_Complex _Float16' is invalid}} } -#endif + Index: clang/test/CodeGen/X86/Float16-complex.c =================================================================== --- clang/test/CodeGen/X86/Float16-complex.c +++ clang/test/CodeGen/X86/Float16-complex.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -target-feature +avx512fp16 -o - | FileCheck %s --check-prefix=X86 +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s --check-prefixes=X86 _Float16 _Complex add_half_rr(_Float16 a, _Float16 b) { // X86-LABEL: @add_half_rr( Index: clang/test/CodeGen/X86/Float16-arithmetic.c =================================================================== --- /dev/null +++ clang/test/CodeGen/X86/Float16-arithmetic.c @@ -0,0 +1,97 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK + +_Float16 add1(_Float16 a, _Float16 b) { + // CHECK-LABEL: define {{.*}} half @add1 + // CHECK: alloca half + // CHECK: alloca half + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: fadd float {{.*}}, {{.*}} + // CHECK: fptrunc float {{.*}} to half + // CHECK: ret half + return a + b; +} + +_Float16 add2(_Float16 a, _Float16 b, _Float16 c) { + // CHECK-LABEL: define dso_local half @add2 + // CHECK: alloca half + // CHECK: alloca half + // CHECK: alloca half + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: fadd float {{.*}}, {{.*}} + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: fadd float {{.*}}, {{.*}} + // CHECK: fptrunc float {{.*}} to half + // CHECK: ret half + return a + b + c; +} + +_Float16 div(_Float16 a, _Float16 b) { + // CHECK-LABEL: define dso_local half @div + // CHECK: alloca half + // CHECK: alloca half + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: fdiv float {{.*}}, {{.*}} + // CHECK: fptrunc float {{.*}} to half + // CHECK: ret half + return a / b; +} + +_Float16 mul(_Float16 a, _Float16 b) { + // CHECK-LABEL: define dso_local half @mul + // CHECK: alloca half + // CHECK: alloca half + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: load half, ptr{{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: fmul float {{.*}}, {{.*}} + // CHECK: fptrunc float {{.*}} to half + // CHECK: ret half + return a * b; +} + +_Float16 add_and_mull(_Float16 a, _Float16 b, _Float16 c, _Float16 d) { + // CHECK-LABEL: define dso_local half @add_and_mull + // CHECK: alloca half + // CHECK: alloca half + // CHECK: alloca half + // CHECK: alloca half + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: store half {{.*}}, ptr {{.*}} + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: fmul float {{.*}}, {{.*}} + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: fmul float {{.*}}, {{.*}} + // CHECK: fadd float {{.*}}, {{.*}} + // CHECK: fptrunc float {{.*}} to half + // CHECK: ret half + return a * b + c * d; +} Index: clang/lib/CodeGen/CGExprScalar.cpp =================================================================== --- clang/lib/CodeGen/CGExprScalar.cpp +++ clang/lib/CodeGen/CGExprScalar.cpp @@ -218,11 +218,12 @@ CGBuilderTy &Builder; bool IgnoreResultAssign; llvm::LLVMContext &VMContext; + QualType PromotionType; // Promotion type public: - ScalarExprEmitter(CodeGenFunction &cgf, bool ira=false) + ScalarExprEmitter(CodeGenFunction &cgf, QualType Ty, bool ira=false) : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira), - VMContext(cgf.getLLVMContext()) { + VMContext(cgf.getLLVMContext()), PromotionType(Ty) { } //===--------------------------------------------------------------------===// @@ -1312,7 +1313,6 @@ return EmitConversionToBool(Src, SrcType); llvm::Type *DstTy = ConvertType(DstType); - // Cast from half through float if half isn't a native type. if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { // Cast to FP using the intrinsic if the half type itself isn't supported. @@ -3053,9 +3053,22 @@ BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) { TestAndClearIgnoreResultAssign(); BinOpInfo Result; - Result.LHS = Visit(E->getLHS()); - Result.RHS = Visit(E->getRHS()); - Result.Ty = E->getType(); + if (!PromotionType.isNull()) { + Result.LHS = + EmitScalarCast(Visit(E->getLHS()), E->getType(), E->getType(), + ConvertType(E->getType()), ConvertType(PromotionType), + ScalarConversionOpts()); + Result.RHS = + EmitScalarCast(Visit(E->getRHS()), E->getType(), E->getType(), + ConvertType(E->getType()), ConvertType(PromotionType), + ScalarConversionOpts()); + Result.Ty = PromotionType; + } + else { + Result.LHS = Visit(E->getLHS()); + Result.RHS = Visit(E->getRHS()); + Result.Ty = E->getType(); + } Result.Opcode = E->getOpcode(); Result.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts()); Result.E = E; @@ -4869,8 +4882,15 @@ Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) { assert(E && hasScalarEvaluationKind(E->getType()) && "Invalid scalar expression to emit"); - - return ScalarExprEmitter(*this, IgnoreResultAssign) + QualType PromotionTy; + if (E->getType()->isFloat16Type() ) { + if (getTarget().ShouldEmitWithExcessPrecision()) + PromotionTy = getContext().FloatTy; + return Builder.CreateFPTrunc(ScalarExprEmitter(*this, PromotionTy, false) + .Visit(const_cast<Expr *>(E)), + ConvertType(E->getType()), "conv"); + } + return ScalarExprEmitter(*this, PromotionTy, IgnoreResultAssign) .Visit(const_cast<Expr *>(E)); } @@ -4881,7 +4901,7 @@ SourceLocation Loc) { assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) && "Invalid scalar expression to emit"); - return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc); + return ScalarExprEmitter(*this, QualType()).EmitScalarConversion(Src, SrcTy, DstTy, Loc); } /// Emit a conversion from the specified complex type to the specified @@ -4892,7 +4912,7 @@ SourceLocation Loc) { assert(SrcTy->isAnyComplexType() && hasScalarEvaluationKind(DstTy) && "Invalid complex -> scalar conversion"); - return ScalarExprEmitter(*this) + return ScalarExprEmitter(*this, QualType()) .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc); } @@ -4900,7 +4920,7 @@ llvm::Value *CodeGenFunction:: EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre) { - return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre); + return ScalarExprEmitter(*this, QualType()).EmitScalarPrePostIncDec(E, LV, isInc, isPre); } LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) { @@ -4925,7 +4945,7 @@ LValue CodeGenFunction::EmitCompoundAssignmentLValue( const CompoundAssignOperator *E) { - ScalarExprEmitter Scalar(*this); + ScalarExprEmitter Scalar(*this, QualType()); Value *Result = nullptr; switch (E->getOpcode()) { #define COMPOUND_OP(Op) \ Index: clang/lib/Basic/Targets/X86.h =================================================================== --- clang/lib/Basic/Targets/X86.h +++ clang/lib/Basic/Targets/X86.h @@ -286,6 +286,10 @@ return false; } + bool ShouldEmitWithExcessPrecision() const { + return HasFloat16 && !hasLegalHalfType(); + } + void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; Index: clang/lib/Basic/Targets/X86.cpp =================================================================== --- clang/lib/Basic/Targets/X86.cpp +++ clang/lib/Basic/Targets/X86.cpp @@ -240,6 +240,7 @@ } else if (Feature == "+avx512fp16") { HasAVX512FP16 = true; HasFloat16 = true; + HasLegalHalfType = true; } else if (Feature == "+avx512pf") { HasAVX512PF = true; } else if (Feature == "+avx512dq") { @@ -369,6 +370,8 @@ .Default(NoXOP); XOPLevel = std::max(XOPLevel, XLevel); } + // Turn on _float16 for x86 (feature sse2) + HasFloat16 = SSELevel >= SSE2; // LLVM doesn't have a separate switch for fpmath, so only accept it if it // matches the selected sse level. Index: clang/include/clang/Basic/TargetInfo.h =================================================================== --- clang/include/clang/Basic/TargetInfo.h +++ clang/include/clang/Basic/TargetInfo.h @@ -897,6 +897,10 @@ return true; } + virtual bool ShouldEmitWithExcessPrecision() const { + return false; + } + /// Specify if mangling based on address space map should be used or /// not for language specific address spaces bool useAddressSpaceMapMangling() const { Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -452,6 +452,9 @@ DWARF Support in Clang ---------------------- +- Support for ``AVX512-FP16`` instructions has been added. +- Support for ``_Float16`` type has been added. + Arm and AArch64 Support in Clang -------------------------------- Index: clang/docs/LanguageExtensions.rst =================================================================== --- clang/docs/LanguageExtensions.rst +++ clang/docs/LanguageExtensions.rst @@ -743,7 +743,7 @@ * 64-bit ARM (AArch64) * AMDGPU * SPIR -* X86 (Only available under feature AVX512-FP16) +* X86 (Enabled with feature SSE2 and up) ``_Float16`` will be supported on more targets as they define ABIs for it.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits