Index: lib/CodeGen/CGExprScalar.cpp =================================================================== --- lib/CodeGen/CGExprScalar.cpp +++ lib/CodeGen/CGExprScalar.cpp @@ -773,8 +773,13 @@ DstTy); // Cast to half via float - if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) + if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { + if (SrcTy->isFloatingPointTy()) + return Builder.CreateCall( + CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, SrcTy), Src); + DstTy = CGF.FloatTy; + } if (isa(SrcTy)) { bool InputSigned = SrcType->isSignedIntegerOrEnumerationType(); Index: test/CodeGen/fp16-ops.c =================================================================== --- test/CodeGen/fp16-ops.c +++ test/CodeGen/fp16-ops.c @@ -5,6 +5,7 @@ volatile cond_t test; volatile __fp16 h0 = 0.0, h1 = 1.0, h2; volatile float f0, f1, f2; +volatile double d0; void foo(void) { // CHECK-LABEL: define void @foo() @@ -52,7 +53,7 @@ // CHECK: call float @llvm.convert.from.fp16.f32( // CHECK: fmul float // CHECK: call i16 @llvm.convert.to.fp16.f32( - h1 = h0 * (__fp16) -2.0; + h1 = h0 * (__fp16) -2.0f; // CHECK: call float @llvm.convert.from.fp16.f32( // CHECK: fmul float // CHECK: call i16 @llvm.convert.to.fp16.f32( @@ -71,7 +72,7 @@ // CHECK: call float @llvm.convert.from.fp16.f32( // CHECK: fdiv float // CHECK: call i16 @llvm.convert.to.fp16.f32( - h1 = (h0 / (__fp16) -2.0); + h1 = (h0 / (__fp16) -2.0f); // CHECK: call float @llvm.convert.from.fp16.f32( // CHECK: fdiv float // CHECK: call i16 @llvm.convert.to.fp16.f32( @@ -109,7 +110,7 @@ // CHECK: call float @llvm.convert.from.fp16.f32( // CHECK: fsub float // CHECK: call i16 @llvm.convert.to.fp16.f32( - h1 = ((__fp16)-2.0 - h0); + h1 = ((__fp16)-2.0f - h0); // CHECK: call float @llvm.convert.from.fp16.f32( // CHECK: fsub float // CHECK: call i16 @llvm.convert.to.fp16.f32( @@ -218,7 +219,7 @@ // Check assignments (inc. compound) h0 = h1; // CHECK: call i16 @llvm.convert.to.fp16.f32( - h0 = (__fp16)-2.0; + h0 = (__fp16)-2.0f; // CHECK: call i16 @llvm.convert.to.fp16.f32( h0 = f0; @@ -231,7 +232,7 @@ // CHECK: call float @llvm.convert.from.fp16.f32( // CHECK: fadd // CHECK: call i16 @llvm.convert.to.fp16.f32( - h0 += (__fp16)1.0; + h0 += (__fp16)1.0f; // CHECK: call float @llvm.convert.from.fp16.f32( // CHECK: fadd // CHECK: call i16 @llvm.convert.to.fp16.f32( @@ -282,3 +283,12 @@ // CHECK: call i16 @llvm.convert.to.fp16.f32( h0 /= f2; } + +void test_trunc() { + // CHECK: call i16 @llvm.convert.to.fp16.f64( + h0 = d0; + + // CHECK: [[MID:%.*]] = fptrunc double {{%.*}} to float + // CHECK: call i16 @llvm.convert.to.fp16.f32(float [[MID]]) + h0 = (float)d0; +}