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

Reply via email to