diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index d234a0566e191..05e264fe722f7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1925,7 +1925,9 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) { II->getOperandBundlesAsDefs(OpBundles); CallInst *NewCI = CallInst::Create(Overload, {InnerTrunc}, OpBundles, II->getName()); - NewCI->copyFastMathFlags(II); + // A normal value may be converted to an infinity. It means that we cannot + // propagate ninf from the intrinsic. So we propagate FMF from fptrunc. + NewCI->copyFastMathFlags(&FPT); return NewCI; } } diff --git a/llvm/test/Transforms/InstCombine/fabs.ll b/llvm/test/Transforms/InstCombine/fabs.ll index 0a22d1431b5f1..0d9374410a1d8 100644 --- a/llvm/test/Transforms/InstCombine/fabs.ll +++ b/llvm/test/Transforms/InstCombine/fabs.ll @@ -1522,7 +1522,7 @@ define float @test_fabs_nsz_used_by_frem(float %x) { define half @test_fabs_nsz_used_by_fptrunc(float %x) { ; CHECK-LABEL: @test_fabs_nsz_used_by_fptrunc( ; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[X:%.*]] to half -; CHECK-NEXT: [[OP:%.*]] = call nsz half @llvm.fabs.f16(half [[TMP1]]) +; CHECK-NEXT: [[OP:%.*]] = call half @llvm.fabs.f16(half [[TMP1]]) ; CHECK-NEXT: ret half [[OP]] ; %cmp = fcmp oge float %x, 0.000000e+00 diff --git a/llvm/test/Transforms/InstCombine/fpcast.ll b/llvm/test/Transforms/InstCombine/fpcast.ll index d5290b572aefd..1a3faceebf244 100644 --- a/llvm/test/Transforms/InstCombine/fpcast.ll +++ b/llvm/test/Transforms/InstCombine/fpcast.ll @@ -32,7 +32,7 @@ define half @test3(float %a) { define half @test3_fast(float %a) { ; CHECK-LABEL: @test3_fast( ; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half -; CHECK-NEXT: [[C:%.*]] = call half @llvm.fabs.f16(half [[TMP1]]) +; CHECK-NEXT: [[C:%.*]] = call fast half @llvm.fabs.f16(half [[TMP1]]) ; CHECK-NEXT: ret half [[C]] ; %b = call float @llvm.fabs.f32(float %a) @@ -40,6 +40,39 @@ define half @test3_fast(float %a) { ret half %c } +define half @test3_both_ninf(float %a) { +; CHECK-LABEL: @test3_both_ninf( +; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half +; CHECK-NEXT: [[C:%.*]] = call ninf half @llvm.fabs.f16(half [[TMP1]]) +; CHECK-NEXT: ret half [[C]] +; + %b = call ninf float @llvm.fabs.f32(float %a) + %c = fptrunc ninf float %b to half + ret half %c +} + +define half @test3_fabs_ninf(float %a) { +; CHECK-LABEL: @test3_fabs_ninf( +; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half +; CHECK-NEXT: [[C:%.*]] = call half @llvm.fabs.f16(half [[TMP1]]) +; CHECK-NEXT: ret half [[C]] +; + %b = call ninf float @llvm.fabs.f32(float %a) + %c = fptrunc float %b to half + ret half %c +} + +define half @test3_fptrunc_ninf(float %a) { +; CHECK-LABEL: @test3_fptrunc_ninf( +; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half +; CHECK-NEXT: [[C:%.*]] = call ninf half @llvm.fabs.f16(half [[TMP1]]) +; CHECK-NEXT: ret half [[C]] +; + %b = call float @llvm.fabs.f32(float %a) + %c = fptrunc ninf float %b to half + ret half %c +} + define half @fneg_fptrunc(float %a) { ; CHECK-LABEL: @fneg_fptrunc( ; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half