[llvm] cab09e7 - [InstCombine] Propagate FMF from fptrunc when folding `fptrunc fabs(X) -> fabs(fptrunc X)` (#143352)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 15 21:07:50 PDT 2025
Author: Yingwei Zheng
Date: 2025-06-16T12:07:47+08:00
New Revision: cab09e76e0c4c95f44cf90bf2bf7a6eaa15b14b2
URL: https://github.com/llvm/llvm-project/commit/cab09e76e0c4c95f44cf90bf2bf7a6eaa15b14b2
DIFF: https://github.com/llvm/llvm-project/commit/cab09e76e0c4c95f44cf90bf2bf7a6eaa15b14b2.diff
LOG: [InstCombine] Propagate FMF from fptrunc when folding `fptrunc fabs(X) -> fabs(fptrunc X)` (#143352)
Alive2: https://alive2.llvm.org/ce/z/DWV3G3
fptrunc yields infinity when the input cannot fit in the target type. So
ninf should be propagated from fptrunc. For other intrinsics, the
previous check ensures that the result is never an infinity:
https://github.com/llvm/llvm-project/blob/5d3899d293e902124c3602b466031b6b799fb123/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp#L1910-L1917
Closes https://github.com/llvm/llvm-project/issues/143122.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
llvm/test/Transforms/InstCombine/double-float-shrink-2.ll
llvm/test/Transforms/InstCombine/fabs.ll
llvm/test/Transforms/InstCombine/fpcast.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 2db79228bf0e6..d4a2fe5e37ef5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1917,7 +1917,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/double-float-shrink-2.ll b/llvm/test/Transforms/InstCombine/double-float-shrink-2.ll
index f2049e2813ebc..f884d2bd1ab5b 100644
--- a/llvm/test/Transforms/InstCombine/double-float-shrink-2.ll
+++ b/llvm/test/Transforms/InstCombine/double-float-shrink-2.ll
@@ -449,7 +449,7 @@ define float @test_shrink_intrin_fabs_fast_double_src(double %D) {
; CHECK-NEXT: ret float [[F]]
;
%E = call fast double @llvm.fabs.f64(double %D)
- %F = fptrunc double %E to float
+ %F = fptrunc fast double %E to float
ret float %F
}
@@ -611,7 +611,7 @@ define half @test_mismatched_type_intrin_fabs_fast_double_src(double %D) {
; CHECK-NEXT: ret half [[F]]
;
%E = call fast double @llvm.fabs.f64(double %D)
- %F = fptrunc double %E to half
+ %F = fptrunc fast double %E to half
ret half %F
}
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
More information about the llvm-commits
mailing list