[llvm] [InstCombine] Fix FMF propagation in `copysign Mag, (copysign ?, X) -> copysign Mag, X` (PR #121574)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 5 23:26:23 PST 2025
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/121574
>From 4cd2b4ad12200e91c29b39ee3703a1e96aa16529 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 3 Jan 2025 22:10:04 +0800
Subject: [PATCH 1/5] [InstCombine] Add pre-commit tests. NFC.
---
llvm/test/Transforms/InstCombine/copysign.ll | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/copysign.ll b/llvm/test/Transforms/InstCombine/copysign.ll
index abc707acf0cd3f..07175f8405bf28 100644
--- a/llvm/test/Transforms/InstCombine/copysign.ll
+++ b/llvm/test/Transforms/InstCombine/copysign.ll
@@ -90,6 +90,16 @@ define float @copysign_sign_arg(float %x, float %y, float %z) {
ret float %r
}
+define float @copysign_sign_arg_nnan(float %x, float %y, float %z) {
+; CHECK-LABEL: @copysign_sign_arg_nnan(
+; CHECK-NEXT: [[R:%.*]] = call nnan float @llvm.copysign.f32(float [[X:%.*]], float [[Z:%.*]])
+; CHECK-NEXT: ret float [[R]]
+;
+ %s = call nnan float @llvm.copysign.f32(float %y, float %z)
+ %r = call nnan float @llvm.copysign.f32(float %x, float %s)
+ ret float %r
+}
+
define float @fneg_mag(float %x, float %y) {
; CHECK-LABEL: @fneg_mag(
; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float [[X:%.*]], float [[Y:%.*]])
>From c532d57809556f093b8dd88605bed9f86cf35952 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 3 Jan 2025 22:25:27 +0800
Subject: [PATCH 2/5] [InstCombine] Fix FMF propagation in `copysign Mag,
(copysign ?, X) -> copysign Mag, X`
---
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 4 +++-
llvm/test/Transforms/InstCombine/copysign.ll | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index cdb2c11ef046ad..0aae2ea1458cde 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2673,8 +2673,10 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// Propagate sign argument through nested calls:
// copysign Mag, (copysign ?, X) --> copysign Mag, X
Value *X;
- if (match(Sign, m_Intrinsic<Intrinsic::copysign>(m_Value(), m_Value(X))))
+ if (match(Sign, m_Intrinsic<Intrinsic::copysign>(m_Value(), m_Value(X)))) {
+ II->andIRFlags(Sign);
return replaceOperand(*II, 1, X);
+ }
// Clear sign-bit of constant magnitude:
// copysign -MagC, X --> copysign MagC, X
diff --git a/llvm/test/Transforms/InstCombine/copysign.ll b/llvm/test/Transforms/InstCombine/copysign.ll
index 07175f8405bf28..2c92557534708c 100644
--- a/llvm/test/Transforms/InstCombine/copysign.ll
+++ b/llvm/test/Transforms/InstCombine/copysign.ll
@@ -82,7 +82,7 @@ define float @not_known_positive_sign_arg(float %x, float %y) {
define float @copysign_sign_arg(float %x, float %y, float %z) {
; CHECK-LABEL: @copysign_sign_arg(
-; CHECK-NEXT: [[R:%.*]] = call ninf float @llvm.copysign.f32(float [[X:%.*]], float [[Z:%.*]])
+; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float [[X:%.*]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[R]]
;
%s = call reassoc float @llvm.copysign.f32(float %y, float %z)
>From 5580ecd8f41808da8444d48c0a52cd096073f7d0 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 3 Jan 2025 23:02:51 +0800
Subject: [PATCH 3/5] [InstCombine] Create new insts
---
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 0aae2ea1458cde..2fc9f751599049 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2674,8 +2674,12 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// copysign Mag, (copysign ?, X) --> copysign Mag, X
Value *X;
if (match(Sign, m_Intrinsic<Intrinsic::copysign>(m_Value(), m_Value(X)))) {
- II->andIRFlags(Sign);
- return replaceOperand(*II, 1, X);
+ IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
+ Builder.setFastMathFlags(II->getFastMathFlags() &
+ cast<Instruction>(Sign)->getFastMathFlags());
+ Value *CopySign =
+ Builder.CreateBinaryIntrinsic(Intrinsic::copysign, Mag, X);
+ return replaceInstUsesWith(*II, CopySign);
}
// Clear sign-bit of constant magnitude:
>From fb8014c1409867505d49c3a7f0125a6ef74cbb86 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 4 Jan 2025 21:24:55 +0800
Subject: [PATCH 4/5] [InstCombine] Add more tests. NFC.
---
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 3 +--
llvm/test/Transforms/InstCombine/copysign.ll | 10 ++++++++++
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 2fc9f751599049..727ddba3447679 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2677,8 +2677,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
Builder.setFastMathFlags(II->getFastMathFlags() &
cast<Instruction>(Sign)->getFastMathFlags());
- Value *CopySign =
- Builder.CreateBinaryIntrinsic(Intrinsic::copysign, Mag, X);
+ Value *CopySign = Builder.CreateCopySign(Mag, X);
return replaceInstUsesWith(*II, CopySign);
}
diff --git a/llvm/test/Transforms/InstCombine/copysign.ll b/llvm/test/Transforms/InstCombine/copysign.ll
index 2c92557534708c..ee093a709eab34 100644
--- a/llvm/test/Transforms/InstCombine/copysign.ll
+++ b/llvm/test/Transforms/InstCombine/copysign.ll
@@ -100,6 +100,16 @@ define float @copysign_sign_arg_nnan(float %x, float %y, float %z) {
ret float %r
}
+define float @copysign_sign_arg_mixed(float %x, float %y, float %z) {
+; CHECK-LABEL: @copysign_sign_arg_mixed(
+; CHECK-NEXT: [[R:%.*]] = call nsz float @llvm.copysign.f32(float [[X:%.*]], float [[Z:%.*]])
+; CHECK-NEXT: ret float [[R]]
+;
+ %s = call ninf nsz float @llvm.copysign.f32(float %y, float %z)
+ %r = call nnan nsz float @llvm.copysign.f32(float %x, float %s)
+ ret float %r
+}
+
define float @fneg_mag(float %x, float %y) {
; CHECK-LABEL: @fneg_mag(
; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float [[X:%.*]], float [[Y:%.*]])
>From 7d9f1583dc01c6023e7a3e4d1babe9fe38b74124 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 6 Jan 2025 15:25:40 +0800
Subject: [PATCH 5/5] [InstCombine] Remove FastMathFlagGuard. NFC.
---
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 727ddba3447679..5494c70b34b1ef 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2674,10 +2674,9 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// copysign Mag, (copysign ?, X) --> copysign Mag, X
Value *X;
if (match(Sign, m_Intrinsic<Intrinsic::copysign>(m_Value(), m_Value(X)))) {
- IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
- Builder.setFastMathFlags(II->getFastMathFlags() &
- cast<Instruction>(Sign)->getFastMathFlags());
- Value *CopySign = Builder.CreateCopySign(Mag, X);
+ Value *CopySign = Builder.CreateCopySign(
+ Mag, X,
+ II->getFastMathFlags() & cast<Instruction>(Sign)->getFastMathFlags());
return replaceInstUsesWith(*II, CopySign);
}
More information about the llvm-commits
mailing list