]> granicus.if.org Git - clang/commitdiff
[Sema] Promote compound assignment exprs. with fp16 LHS and int. RHS.
authorAhmed Bougacha <ahmed.bougacha@gmail.com>
Fri, 29 May 2015 22:54:57 +0000 (22:54 +0000)
committerAhmed Bougacha <ahmed.bougacha@gmail.com>
Fri, 29 May 2015 22:54:57 +0000 (22:54 +0000)
We catch most of the various other __fp16 implicit conversions to
float, but not this one:

  __fp16 a;
  int i;
  ...
  a += i;

For which we used to generate something 'fun' like:

  %conv = sitofp i32 %i to float
  %1 = tail call i16 @llvm.convert.to.fp16.f32(float %conv)
  %add = add i16 %0, %1

Instead, when we have an __fp16 LHS and an integer RHS, we should
use float as the result type.

While there, add a bunch of missing tests for mixed
__fp16/integer expressions.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@238625 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/CodeGen/fp16-ops.c

index 7ab269c3b6d5e5bd12121717cb80e1e71c6a6928..dfb17f4bbc355ff26e135cb39b415092f4ad0cfe 100644 (file)
@@ -1110,10 +1110,15 @@ static QualType handleFloatConversion(Sema &S, ExprResult &LHS,
     return RHSType;
   }
 
-  if (LHSFloat)
+  if (LHSFloat) {
+    // Half FP has to be promoted to float unless it is natively supported
+    if (LHSType->isHalfType() && !S.getLangOpts().NativeHalfType)
+      LHSType = S.Context.FloatTy;
+
     return handleIntToFloatConversion(S, LHS, RHS, LHSType, RHSType,
                                       /*convertFloat=*/!IsCompAssign,
                                       /*convertInt=*/ true);
+  }
   assert(RHSFloat);
   return handleIntToFloatConversion(S, RHS, LHS, RHSType, LHSType,
                                     /*convertInt=*/ true,
index fe0fa2c2667edbcb3c03f66b8e5f178fb6dcd407..7cd08a03d6420dfb01b291f09dbed87a78f9e706 100644 (file)
@@ -10,6 +10,7 @@
 typedef unsigned cond_t;
 
 volatile cond_t test;
+volatile int i0;
 volatile __fp16 h0 = 0.0, h1 = 1.0, h2;
 volatile float f0, f1, f2;
 volatile double d0;
@@ -91,6 +92,11 @@ void foo(void) {
   // NATIVE-HALF: fpext half
   // NATIVE-HALF: fmul float
   h1 = f0 * h2;
+  // CHECK: [[F16TOF32]]
+  // CHECK: fmul float
+  // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fmul half
+  h1 = h0 * i0;
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -116,6 +122,11 @@ void foo(void) {
   // NATIVE-HALF: fpext half
   // NATIVE-HALF: fdiv float
   h1 = (f0 / h2);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fdiv float
+  // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fdiv half
+  h1 = (h0 / i0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -141,6 +152,11 @@ void foo(void) {
   // NATIVE-HALF: fpext half
   // NATIVE-HALF: fadd float
   h1 = (f2 + h0);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fadd float
+  // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fadd half
+  h1 = (h0 + i0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -166,6 +182,11 @@ void foo(void) {
   // NATIVE-HALF: fpext half
   // NATIVE-HALF: fsub float
   h1 = (f2 - h0);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fsub float
+  // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fsub half
+  h1 = (h0 - i0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -187,6 +208,14 @@ void foo(void) {
   // NATIVE-HALF: fpext half
   // NATIVE-HALF: fcmp olt float
   test = (f2 < h0);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp olt float
+  // NATIVE-HALF: fcmp olt half
+  test = (i0 < h0);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp olt float
+  // NATIVE-HALF: fcmp olt half
+  test = (h0 < i0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -208,6 +237,14 @@ void foo(void) {
   // NATIVE-HALF: fpext half
   // NATIVE-HALF: fcmp ogt float
   test = (f0 > h2);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp ogt float
+  // NATIVE-HALF: fcmp ogt half
+  test = (i0 > h0);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp ogt float
+  // NATIVE-HALF: fcmp ogt half
+  test = (h0 > i0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -229,6 +266,15 @@ void foo(void) {
   // NATIVE-HALF: fpext half
   // NATIVE-HALF: fcmp ole float
   test = (f2 <= h0);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp ole float
+  // NATIVE-HALF: fcmp ole half
+  test = (i0 <= h0);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp ole float
+  // NATIVE-HALF: fcmp ole half
+  test = (h0 <= i0);
+
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -250,6 +296,14 @@ void foo(void) {
   // NATIVE-HALF: fpext half
   // NATIVE-HALF: fcmp oge float
   test = (f0 >= h2);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp oge float
+  // NATIVE-HALF: fcmp oge half
+  test = (i0 >= h0);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp oge float
+  // NATIVE-HALF: fcmp oge half
+  test = (h0 >= i0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -271,6 +325,14 @@ void foo(void) {
   // NATIVE-HALF: fpext half
   // NATIVE-HALF: fcmp oeq float
   test = (f1 == h1);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp oeq float
+  // NATIVE-HALF: fcmp oeq half
+  test = (i0 == h0);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp oeq float
+  // NATIVE-HALF: fcmp oeq half
+  test = (h0 == i0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -292,6 +354,14 @@ void foo(void) {
   // NATIVE-HALF: fpext half
   // NATIVE-HALF: fcmp une float
   test = (f1 != h1);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp une float
+  // NATIVE-HALF: fcmp une half
+  test = (i0 != h0);
+  // CHECK: [[F16TOF32]]
+  // CHECK: fcmp une float
+  // NATIVE-HALF: fcmp une half
+  test = (h0 != i0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp une float
@@ -310,6 +380,15 @@ void foo(void) {
   // NATIVE-HALF: fptrunc float
   h0 = f0;
 
+  // CHECK: sitofp i32 {{.*}} to float
+  // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: sitofp i32 {{.*}} to half
+  h0 = i0;
+  // CHECK: [[F16TOF32]]
+  // CHECK: fptosi float {{.*}} to i32
+  // NATIVE-HALF: fptosi half {{.*}} to i32
+  i0 = h0;
+
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fadd float
@@ -329,6 +408,21 @@ void foo(void) {
   // NATIVE-HALF: fadd float
   // NATIVE-HALF: fptrunc float
   h0 += f2;
+  // CHECK: [[F16TOF32]]
+  // CHECK: sitofp i32 {{.*}} to float
+  // CHECK: fadd float
+  // CHECK: fptosi float {{.*}} to i32
+  // NATIVE-HALF: sitofp i32 {{.*}} to half
+  // NATIVE-HALF: fadd half
+  // NATIVE-HALF: fptosi half {{.*}} to i32
+  i0 += h0;
+  // CHECK: sitofp i32 {{.*}} to float
+  // CHECK: [[F16TOF32]]
+  // CHECK: fadd float
+  // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: sitofp i32 {{.*}} to half
+  // NATIVE-HALF: fadd half
+  h0 += i0;
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -349,6 +443,21 @@ void foo(void) {
   // NATIVE-HALF: fsub float
   // NATIVE-HALF: fptrunc float
   h0 -= f2;
+  // CHECK: [[F16TOF32]]
+  // CHECK: sitofp i32 {{.*}} to float
+  // CHECK: fsub float
+  // CHECK: fptosi float {{.*}} to i32
+  // NATIVE-HALF: sitofp i32 {{.*}} to half
+  // NATIVE-HALF: fsub half
+  // NATIVE-HALF: fptosi half {{.*}} to i32
+  i0 -= h0;
+  // CHECK: sitofp i32 {{.*}} to float
+  // CHECK: [[F16TOF32]]
+  // CHECK: fsub float
+  // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: sitofp i32 {{.*}} to half
+  // NATIVE-HALF: fsub half
+  h0 -= i0;
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -369,6 +478,21 @@ void foo(void) {
   // NATIVE-HALF: fmul float
   // NATIVE-HALF: fptrunc float
   h0 *= f2;
+  // CHECK: [[F16TOF32]]
+  // CHECK: sitofp i32 {{.*}} to float
+  // CHECK: fmul float
+  // CHECK: fptosi float {{.*}} to i32
+  // NATIVE-HALF: sitofp i32 {{.*}} to half
+  // NATIVE-HALF: fmul half
+  // NATIVE-HALF: fptosi half {{.*}} to i32
+  i0 *= h0;
+  // CHECK: sitofp i32 {{.*}} to float
+  // CHECK: [[F16TOF32]]
+  // CHECK: fmul float
+  // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: sitofp i32 {{.*}} to half
+  // NATIVE-HALF: fmul half
+  h0 *= i0;
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
@@ -389,6 +513,21 @@ void foo(void) {
   // NATIVE-HALF: fdiv float
   // NATIVE-HALF: fptrunc float
   h0 /= f2;
+  // CHECK: [[F16TOF32]]
+  // CHECK: sitofp i32 {{.*}} to float
+  // CHECK: fdiv float
+  // CHECK: fptosi float {{.*}} to i32
+  // NATIVE-HALF: sitofp i32 {{.*}} to half
+  // NATIVE-HALF: fdiv half
+  // NATIVE-HALF: fptosi half {{.*}} to i32
+  i0 /= h0;
+  // CHECK: sitofp i32 {{.*}} to float
+  // CHECK: [[F16TOF32]]
+  // CHECK: fdiv float
+  // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: sitofp i32 {{.*}} to half
+  // NATIVE-HALF: fdiv half
+  h0 /= i0;
 
   // Check conversions to/from double
   // NOHALF: call i16 @llvm.convert.to.fp16.f64(