[llvm] c055999 - [InstCombine] Fix FMF propagation in `copysign Mag, (copysign ?, X) -> copysign Mag, X` (#121574)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 6 00:23:49 PST 2025
Author: Yingwei Zheng
Date: 2025-01-06T16:23:46+08:00
New Revision: c05599966cd594c15834378f57669719d221c4d4
URL: https://github.com/llvm/llvm-project/commit/c05599966cd594c15834378f57669719d221c4d4
DIFF: https://github.com/llvm/llvm-project/commit/c05599966cd594c15834378f57669719d221c4d4.diff
LOG: [InstCombine] Fix FMF propagation in `copysign Mag, (copysign ?, X) -> copysign Mag, X` (#121574)
Closes https://github.com/llvm/llvm-project/issues/121432.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/test/Transforms/InstCombine/copysign.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index cdb2c11ef046ad..5494c70b34b1ef 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2673,8 +2673,12 @@ 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))))
- return replaceOperand(*II, 1, X);
+ if (match(Sign, m_Intrinsic<Intrinsic::copysign>(m_Value(), m_Value(X)))) {
+ Value *CopySign = Builder.CreateCopySign(
+ Mag, X,
+ II->getFastMathFlags() & cast<Instruction>(Sign)->getFastMathFlags());
+ return replaceInstUsesWith(*II, CopySign);
+ }
// 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 abc707acf0cd3f..ee093a709eab34 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)
@@ -90,6 +90,26 @@ 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 @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