[llvm] [InstCombine] Propagate FMF from fptrunc when folding `fptrunc fabs(X) -> fabs(fptrunc X)` (PR #143352)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 13 07:42:21 PDT 2025
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/143352
>From 332aa187f1c2badb7f2652901952a9fd24e6c50e Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 9 Jun 2025 15:19:23 +0800
Subject: [PATCH 1/4] [InstCombine] Add pre-commit tests. NFC.
---
llvm/test/Transforms/InstCombine/fpcast.ll | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/fpcast.ll b/llvm/test/Transforms/InstCombine/fpcast.ll
index d5290b572aefd..a2f14a7313ecd 100644
--- a/llvm/test/Transforms/InstCombine/fpcast.ll
+++ b/llvm/test/Transforms/InstCombine/fpcast.ll
@@ -40,6 +40,28 @@ 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 ninf 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 @fneg_fptrunc(float %a) {
; CHECK-LABEL: @fneg_fptrunc(
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half
>From 2b1fe7efd3353c78b056f190692a0e288a9ad035 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 9 Jun 2025 15:36:04 +0800
Subject: [PATCH 2/4] [InstCombine] Drop ninf when folding `fptrunc(fabs(X)) ->
fabs()fpfptrunc X)`
---
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 3 +++
llvm/test/Transforms/InstCombine/fpcast.ll | 4 ++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 2db79228bf0e6..cdb417faf0208 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1918,6 +1918,9 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
CallInst *NewCI =
CallInst::Create(Overload, {InnerTrunc}, OpBundles, II->getName());
NewCI->copyFastMathFlags(II);
+ // A normal value may be converted to an infinity.
+ if (II->getIntrinsicID() == Intrinsic::fabs)
+ NewCI->setHasNoInfs(FPT.hasNoInfs());
return NewCI;
}
}
diff --git a/llvm/test/Transforms/InstCombine/fpcast.ll b/llvm/test/Transforms/InstCombine/fpcast.ll
index a2f14a7313ecd..adc1dc5f99d6d 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 ninf half @llvm.fabs.f16(half [[TMP1]])
; CHECK-NEXT: ret half [[C]]
;
%b = call float @llvm.fabs.f32(float %a)
@@ -54,7 +54,7 @@ define half @test3_both_ninf(float %a) {
define half @test3_fabs_ninf(float %a) {
; CHECK-LABEL: @test3_fabs_ninf(
; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half
-; CHECK-NEXT: [[C:%.*]] = call ninf half @llvm.fabs.f16(half [[TMP1]])
+; CHECK-NEXT: [[C:%.*]] = call half @llvm.fabs.f16(half [[TMP1]])
; CHECK-NEXT: ret half [[C]]
;
%b = call ninf float @llvm.fabs.f32(float %a)
>From 5a8aa30dce21fa25d35706733c283bd059113095 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 9 Jun 2025 15:40:25 +0800
Subject: [PATCH 3/4] [InstCombine] Add more tests. NFC.
---
llvm/test/Transforms/InstCombine/fpcast.ll | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/fpcast.ll b/llvm/test/Transforms/InstCombine/fpcast.ll
index adc1dc5f99d6d..2af4b85dd32eb 100644
--- a/llvm/test/Transforms/InstCombine/fpcast.ll
+++ b/llvm/test/Transforms/InstCombine/fpcast.ll
@@ -62,6 +62,17 @@ define half @test3_fabs_ninf(float %a) {
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
>From 6251f7dc0aeda8acb4f1a54089c34f819432cc68 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 9 Jun 2025 18:49:18 +0800
Subject: [PATCH 4/4] [InstCombine] Always propagate FMF from fptrunc
---
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 7 +++----
llvm/test/Transforms/InstCombine/fabs.ll | 2 +-
llvm/test/Transforms/InstCombine/fpcast.ll | 2 +-
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index cdb417faf0208..d4a2fe5e37ef5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1917,10 +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.
- if (II->getIntrinsicID() == Intrinsic::fabs)
- NewCI->setHasNoInfs(FPT.hasNoInfs());
+ // 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 2af4b85dd32eb..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 ninf 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)
More information about the llvm-commits
mailing list