[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
Sat Jan 4 05:33:05 PST 2025


https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/121574

>From d29db5d57e2fadf998f9d10fb4877608b5ff8f97 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/4] [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 0faae17e4d393a263678a1243cf48a6f3d2a6d0c 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/4] [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 fd38738e3be80b..6624a40a781d9f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2644,8 +2644,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 c7f8685662f84276e33d04b654fb3d7adb1cad6c 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/4] [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 6624a40a781d9f..0850f9343d7564 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2645,8 +2645,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 f5bf1a921434c1d856c8d6ed4fda6fcbb3563722 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/4] [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 0850f9343d7564..028a4cedb78b9a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2648,8 +2648,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:%.*]])



More information about the llvm-commits mailing list