zahiraam updated this revision to Diff 439385. 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/CGExprComplex.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/lib/CodeGen/CodeGenFunction.h 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-PROM _Float16 _Complex add_half_rr(_Float16 a, _Float16 b) { // X86-LABEL: @add_half_rr( @@ -85,7 +86,29 @@ return a * b; } _Float16 _Complex mul_half_cc(_Float16 _Complex a, _Float16 _Complex b) { - // X86-LABEL: @mul_half_cc( + // CHECK: @mul_half_cc( + + // X86-PROM: fpext half {{.*}} to float + // X86-PROM: fpext half {{.*}} to float + // X86-PROM: fpext half {{.*}} to float + // X86-PROM: fpext half {{.*}} to float + // X86-PROM: %[[AC:[^ ]+]] = fmul float + // X86-PROM: %[[BD:[^ ]+]] = fmul float + // X86-PROM: %[[AD:[^ ]+]] = fmul float + // X86-PROM: %[[BC:[^ ]+]] = fmul float + // X86-PROM: %[[RR:[^ ]+]] = fsub float + // X86-PROM: %[[RI:[^ ]+]] = fadd float + // X86-PROM: fcmp uno float %[[RR]] + // X86-PROM: fcmp uno float %[[RI]] + // X86-PROM: call <2 x float> @__mulsc3( + // X86-PROM: fptrunc float {{.*}} to half + // X86-PROM: fptrunc float {{.*}} to half + // X86-PROM: %[[RETR:[^ ]+]] = getelementptr inbounds { half, half } + // X86-PROM: %[[RETI:[^ ]+]] = getelementptr inbounds { half, half } + // X86-PROM: store half {{.*}}, ptr %[[RETR]] + // X86-PROM: store half {{.*}}, ptr %[[RETI]] + // X86-PROM: load <2 x half>, ptr {{.*}} + // X86: %[[AC:[^ ]+]] = fmul // X86: %[[BD:[^ ]+]] = fmul // X86: %[[AD:[^ ]+]] = fmul @@ -98,7 +121,8 @@ // X86: fcmp uno half %[[RR]] // X86: fcmp uno half %[[RI]] // X86: call {{.*}} @__mulhc3( - // X86: ret + + // CHECK: ret return a * b; } @@ -118,10 +142,32 @@ return a / b; } _Float16 _Complex div_half_rc(_Float16 a, _Float16 _Complex b) { - // X86-LABEL: @div_half_rc( + // CHECK: @div_half_rc( // X86-NOT: fdiv // X86: call {{.*}} @__divhc3( - // X86: ret + + // X86-PROM: load half + // X86-PROM: fpext half {{.*}} to float + // X86-PROM: getelementptr inbounds { half, half } + // X86-PROM: load half + // X86-PROM: getelementptr inbounds { half, half } + // X86-PROM: load half + // X86-PROM: fpext half {{.*}} to float + // X86-PROM: fpext half {{.*}} to float + // X86-PROM: call {{.*}} @__divsc3( + // X86-PROM: getelementptr inbounds { float, float } + // X86-PROM: load float + // X86-PROM: getelementptr inbounds { float, float } + // X86-PROM: load float + // X86-PROM: fptrunc float {{.*}} to half + // X86-PROM: fptrunc float {{.*}} to half + // X86-PROM: getelementptr inbounds { half, half } + // X86-PROM: getelementptr inbounds { half, half } + // X86-PROM: store half {{.*}} + // X86-PROM: store half {{.*}} + + // CHECK: ret + return a / b; } _Float16 _Complex div_half_cc(_Float16 _Complex a, _Float16 _Complex b) { Index: clang/test/CodeGen/X86/Float16-arithmetic.c =================================================================== --- /dev/null +++ clang/test/CodeGen/X86/Float16-arithmetic.c @@ -0,0 +1,120 @@ +// 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_mul1(_Float16 a, _Float16 b, _Float16 c, _Float16 d) { + // CHECK-LABEL: define dso_local half @add_and_mul1 + // 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; +} + +_Float16 add_and_mul2(_Float16 a, _Float16 b, _Float16 c, _Float16 d) { + // 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 {{.*}}, align 2 + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: load half, ptr {{.*}}, align 2 + // CHECK: fpext half {{.*}} to float + // CHECK: fmul float 6.000000e+00, {{.*}} + // CHECK: fsub float {{.*}}, {{.*}} + // CHECK: load half, ptr {{.*}} + // CHECK: fpext half {{.*}} to float + // CHECK: fadd float {{.*}}, {{.*}} + // CHECK: fptrunc float {{.*}} to half + // CHECK: ret half {{.*}} + return (a - 6*b)+c; +} Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -4404,6 +4404,10 @@ /// EmitLoadOfComplex - Load a complex number from the specified l-value. ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc); + ComplexPairTy EmitPromotedComplexExpr(ComplexPairTy E, QualType DstTy); + llvm::Value *EmitPromotedScalarExpr(const Expr *E, + QualType DstType); + Address emitAddrOfRealComponent(Address complex, QualType complexType); Address emitAddrOfImagComponent(Address complex, QualType complexType); Index: clang/lib/CodeGen/CGExprScalar.cpp =================================================================== --- clang/lib/CodeGen/CGExprScalar.cpp +++ clang/lib/CodeGen/CGExprScalar.cpp @@ -791,7 +791,10 @@ // Helper functions for fixed point binary operations. Value *EmitFixedPointBinOp(const BinOpInfo &Ops); - BinOpInfo EmitBinOps(const BinaryOperator *E); + BinOpInfo EmitBinOps(const BinaryOperator *E, + QualType PromotionTy = QualType()); + Value *EmitPromoted(const Expr *E, QualType PromotionTy); + LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E, Value *(ScalarExprEmitter::*F)(const BinOpInfo &), Value *&Result); @@ -799,13 +802,27 @@ Value *EmitCompoundAssign(const CompoundAssignOperator *E, Value *(ScalarExprEmitter::*F)(const BinOpInfo &)); + QualType getPromotionType(const Expr *E) { + if (E->getType()->isFloat16Type()) { + if (CGF.getTarget().shouldEmitFloat16WithExcessPrecision()) + return CGF.getContext().FloatTy; + } + return QualType(); + } + // Binary operators and binary compound assignment operators. -#define HANDLEBINOP(OP) \ - Value *VisitBin ## OP(const BinaryOperator *E) { \ - return Emit ## OP(EmitBinOps(E)); \ - } \ - Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \ - return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \ +#define HANDLEBINOP(OP) \ + Value *VisitBin##OP(const BinaryOperator *E) { \ + QualType promotionTy = getPromotionType(E); \ + auto result = Emit##OP(EmitBinOps(E, promotionTy)); \ + if (result) \ + if (!promotionTy.isNull()) \ + result = Builder.CreateFPTrunc(result, ConvertType(E->getType()), \ + "unpromotion"); \ + return result; \ + } \ + Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \ + return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \ } HANDLEBINOP(Mul) HANDLEBINOP(Div) @@ -3050,12 +3067,24 @@ // Binary Operators //===----------------------------------------------------------------------===// -BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) { +Value *ScalarExprEmitter::EmitPromoted(const Expr *E, QualType DstType) { + return EmitScalarCast(Visit(const_cast<Expr *>(E)), E->getType(), + E->getType(), ConvertType(E->getType()), + ConvertType(DstType), ScalarConversionOpts()); +} + +BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E, QualType PromotionType) { TestAndClearIgnoreResultAssign(); BinOpInfo Result; - Result.LHS = Visit(E->getLHS()); - Result.RHS = Visit(E->getRHS()); - Result.Ty = E->getType(); + if (!PromotionType.isNull()) { + Result.LHS = CGF.EmitPromotedScalarExpr(E->getLHS(), PromotionType); + Result.RHS = CGF.EmitPromotedScalarExpr(E->getRHS(), PromotionType); + 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; @@ -4896,6 +4925,12 @@ .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc); } +Value * +CodeGenFunction::EmitPromotedScalarExpr(const Expr *E, + QualType DstType) { + return ScalarExprEmitter(*this).EmitPromoted(E, DstType); +} + llvm::Value *CodeGenFunction:: EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, Index: clang/lib/CodeGen/CGExprComplex.cpp =================================================================== --- clang/lib/CodeGen/CGExprComplex.cpp +++ clang/lib/CodeGen/CGExprComplex.cpp @@ -253,7 +253,13 @@ QualType Ty; // Computation Type. }; - BinOpInfo EmitBinOps(const BinaryOperator *E); + llvm::Value *EmitPromotedValue(ComplexPairTy Src, + llvm::Type *SrcTy, + QualType DstTy, + SourceLocation Loc); + BinOpInfo EmitBinOps(const BinaryOperator *E, + QualType PromotionTy = QualType()); + ComplexPairTy EmitPromoted(ComplexPairTy E, QualType PromotionTy); LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E, ComplexPairTy (ComplexExprEmitter::*Func) (const BinOpInfo &), @@ -270,18 +276,43 @@ ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName, const BinOpInfo &Op); - ComplexPairTy VisitBinAdd(const BinaryOperator *E) { - return EmitBinAdd(EmitBinOps(E)); - } - ComplexPairTy VisitBinSub(const BinaryOperator *E) { - return EmitBinSub(EmitBinOps(E)); - } - ComplexPairTy VisitBinMul(const BinaryOperator *E) { - return EmitBinMul(EmitBinOps(E)); - } - ComplexPairTy VisitBinDiv(const BinaryOperator *E) { - return EmitBinDiv(EmitBinOps(E)); - } + QualType getPromotionType(const Expr *E) { + assert(E->getType()->isAnyComplexType() && + "Expecting to promote a complex type!"); + QualType ElementType = + E->getType()->castAs<ComplexType>()->getElementType(); + if (ElementType->isFloat16Type()) + if (CGF.getTarget().shouldEmitFloat16WithExcessPrecision()) + return CGF.getContext().getComplexType(CGF.getContext().FloatTy); + return QualType(); + } + +#define HANDLEBINOP(OP) \ + ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \ + QualType promotionTy = getPromotionType(E); \ + ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \ + if (!promotionTy.isNull()) { \ + if (result.first) \ + result.first = Builder.CreateFPTrunc( \ + result.first, \ + CGF.ConvertType( \ + E->getType()->castAs<ComplexType>()->getElementType()), \ + "unpromotion"); \ + if (result.second) \ + result.second = Builder.CreateFPTrunc( \ + result.second, \ + CGF.ConvertType( \ + E->getType()->castAs<ComplexType>()->getElementType()), \ + "unpromotion"); \ + } \ + return result; \ + } + + HANDLEBINOP(Mul) + HANDLEBINOP(Div) + HANDLEBINOP(Add) + HANDLEBINOP(Sub) +#undef HANDLEBINOP ComplexPairTy VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) { return Visit(E->getSemanticForm()); @@ -876,21 +907,76 @@ return ComplexPairTy(DSTr, DSTi); } +llvm::Value *ComplexExprEmitter::EmitPromotedValue(ComplexPairTy Src, + llvm::Type *SrcTy, + QualType DstTy, + SourceLocation Loc) { + DstTy = DstTy->castAs<ComplexType>()->getElementType(); + llvm::Type *SrcElementTy = SrcTy; + llvm::Type *DstElementTy = CGF.ConvertType(DstTy); + assert(DstElementTy->getTypeID() > SrcElementTy->getTypeID() && + "We are not expecting to land here, since we are promoting to a " + "larger type size"); + return Builder.CreateFPExt(Src.first, DstElementTy, "conv"); +} +ComplexPairTy ComplexExprEmitter::EmitPromoted(ComplexPairTy RHS, + QualType PromotionTy) { + llvm::Value *RHSr = EmitPromotedValue(RHS, RHS.first->getType(), PromotionTy, + SourceLocation()); + llvm::Value *RHSi = EmitPromotedValue(RHS, RHS.second->getType(), PromotionTy, + SourceLocation()); + return ComplexPairTy(RHSr, RHSi); + } + +ComplexPairTy CodeGenFunction::EmitPromotedComplexExpr(ComplexPairTy E, + QualType DstTy) { + return ComplexExprEmitter(*this).EmitPromoted(E, DstTy); +} + + ComplexExprEmitter::BinOpInfo -ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) { +ComplexExprEmitter::EmitBinOps(const BinaryOperator *E, + QualType PromotionType) { TestAndClearIgnoreReal(); TestAndClearIgnoreImag(); BinOpInfo Ops; - if (E->getLHS()->getType()->isRealFloatingType()) - Ops.LHS = ComplexPairTy(CGF.EmitScalarExpr(E->getLHS()), nullptr); - else - Ops.LHS = Visit(E->getLHS()); - if (E->getRHS()->getType()->isRealFloatingType()) - Ops.RHS = ComplexPairTy(CGF.EmitScalarExpr(E->getRHS()), nullptr); - else - Ops.RHS = Visit(E->getRHS()); - Ops.Ty = E->getType(); + if (E->getLHS()->getType()->isRealFloatingType()) { + if (!PromotionType.isNull()) + Ops.LHS = ComplexPairTy( + CGF.EmitPromotedScalarExpr( + E->getLHS(), + PromotionType->castAs<ComplexType>()->getElementType()), + nullptr); + else + Ops.LHS = ComplexPairTy(CGF.EmitScalarExpr(E->getLHS()), nullptr); + } else { + if (!PromotionType.isNull()) + Ops.LHS = ComplexPairTy( + CGF.EmitPromotedComplexExpr(Visit(E->getLHS()), PromotionType)); + else + Ops.LHS = Visit(E->getLHS()); + } + if (E->getRHS()->getType()->isRealFloatingType()) { + if (!PromotionType.isNull()) + Ops.RHS = ComplexPairTy( + CGF.EmitPromotedScalarExpr( + E->getRHS(), + PromotionType->castAs<ComplexType>()->getElementType()), + nullptr); + else + Ops.RHS = ComplexPairTy(CGF.EmitScalarExpr(E->getRHS()), nullptr); + } else { + if (!PromotionType.isNull()) + Ops.RHS = ComplexPairTy( + CGF.EmitPromotedComplexExpr(Visit(E->getRHS()), PromotionType)); + else + Ops.RHS = Visit(E->getRHS()); + } + if (!PromotionType.isNull()) + Ops.Ty = PromotionType; + else + Ops.Ty = E->getType(); return Ops; } 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 shouldEmitFloat16WithExcessPrecision() 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 @@ -239,7 +239,7 @@ HasAVX512ER = true; } else if (Feature == "+avx512fp16") { HasAVX512FP16 = true; - HasFloat16 = true; + HasLegalHalfType = true; } else if (Feature == "+avx512pf") { HasAVX512PF = true; } else if (Feature == "+avx512dq") { @@ -369,6 +369,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 @@ -909,6 +909,10 @@ return true; } + virtual bool shouldEmitFloat16WithExcessPrecision() 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 @@ -515,6 +515,8 @@ handled incorrectly by some software (e.g. new failures with incorrect assertions). +- 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