[Sema] Promote compound assignment exprs. with fp16 LHS and int. RHS.
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. llvm-svn: 238625
This commit is contained in:
parent
32a9da5668
commit
5b63908f9f
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue