-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[InstCombine] Fix FMF propagation in copysign Mag, (copysign ?, X) -> copysign Mag, X
#121574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesCloses #121432. Full diff: https://github.com/llvm/llvm-project/pull/121574.diff 2 Files Affected:
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 abc707acf0cd3f..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)
@@ -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:%.*]])
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we create a new call here instead of modifying the operand? Otherwise there would still be a potential problem with nofpclass on the argument.
Builder.setFastMathFlags(II->getFastMathFlags() & | ||
cast<Instruction>(Sign)->getFastMathFlags()); | ||
Value *CopySign = | ||
Builder.CreateBinaryIntrinsic(Intrinsic::copysign, Mag, X); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We really ought to add FMF arguments to all these CreateFunctions, the guard + set is so clumsy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am working on a prototype.
f5bf1a9
to
7d9f158
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Closes #121432.