-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[InstSimplify] Simplify (fmul -x, +/-0)
-> -/+0
#85345
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
(fmul -x, +/-0)
-> -/+0
@llvm/pr-subscribers-llvm-analysis @llvm/pr-subscribers-llvm-transforms Author: None (goldsteinn) Changes
Full diff: https://github.com/llvm/llvm-project/pull/85345.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index ce651783caf16b..434ee26ef01aa5 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5767,11 +5767,18 @@ static Value *simplifyFMAFMul(Value *Op0, Value *Op1, FastMathFlags FMF,
if (FMF.noNaNs() && FMF.noSignedZeros())
return ConstantFP::getZero(Op0->getType());
- // +normal number * (-)0.0 --> (-)0.0
KnownFPClass Known =
computeKnownFPClass(Op0, FMF, fcInf | fcNan, /*Depth=*/0, Q);
- if (Known.SignBit == false && Known.isKnownNever(fcInf | fcNan))
- return Op1;
+ if (Known.isKnownNever(fcInf | fcNan)) {
+ // +normal number * (-)0.0 --> (-)0.0
+ if (Known.SignBit == false)
+ return Op1;
+ // -normal number * (-)0.0 --> -(-)0.0
+ if (Known.SignBit == true)
+ return match(Op1, m_PosZeroFP())
+ ? ConstantFP::getNegativeZero(Op0->getType())
+ : ConstantFP::getZero(Op0->getType());
+ }
}
// sqrt(X) * sqrt(X) --> X, if we can:
diff --git a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
index b8244b1d508c62..9b913d68f4004e 100644
--- a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
+++ b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
@@ -211,6 +211,22 @@ define double @fmul_nnan_ninf_nneg_n0.0_commute(i127 %x) {
ret double %r
}
+define float @src_mul_nzero_neg(float nofpclass(inf nan pzero psub pnorm) %f) {
+; CHECK-LABEL: @src_mul_nzero_neg(
+; CHECK-NEXT: ret float 0.000000e+00
+;
+ %r = fmul float %f, -0.0
+ ret float %r
+}
+
+define float @src_mul_zero_neg(float nofpclass(inf nan pzero psub pnorm) %f) {
+; CHECK-LABEL: @src_mul_zero_neg(
+; CHECK-NEXT: ret float -0.000000e+00
+;
+ %r = fmul float %f, 0.0
+ ret float %r
+}
+
; Make sure we can infer %x can't be 0 based on assumes.
define { float, float } @test_fmul_0_assumed_finite(float %x) {
; CHECK-LABEL: @test_fmul_0_assumed_finite(
|
305e930
to
6f53eaa
Compare
%r = fmul float %f, 0.0 | ||
ret float %r | ||
} | ||
|
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 you also test the FMA / fmuladd cases? Also vectors
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.
Done, although neither of those cases get simplified by instsimplify
alone.
if (Known.SignBit == true) | ||
return match(Op1, m_PosZeroFP()) | ||
? ConstantFP::getNegativeZero(Op0->getType()) | ||
: ConstantFP::getZero(Op0->getType()); |
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 also just pass the bool condition to the parameter to getZero to make it signed
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.
Switching to just fneg
, that's necessary for handling mismatch vector.
(fmul -x, +/-0)
-> -/+0
(fmul -x, +/-0)
-> -/+0
We already handle the `+x` case, and noticed it was missing in the bug affecting llvm#82555 Proofs: https://alive2.llvm.org/ce/z/WUSvmV
6f53eaa
to
d84e96c
Compare
; CHECK-NEXT: [[R:%.*]] = call float @llvm.fmuladd.f32(float [[F:%.*]], float 0.000000e+00, float [[ADD:%.*]]) | ||
; CHECK-NEXT: ret float [[R]] | ||
; | ||
%r = call float @llvm.fmuladd.f32(float %f, float 0.0, float %add) |
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 think the case fmuladd/fma will be handled is if the last operand is 0
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.
Doesn't seem to be the case, although note instcombine
does handle the fmuladd
/fma
. Just not simplify.
We already handle the `+x` case, and noticed it was missing in the bug affecting llvm#82555 Proofs: https://alive2.llvm.org/ce/z/WUSvmV Closes llvm#85345
(fmul -x, +/-0)
; NFC(fmul -x, +/-0)
->-/+0
Proofs: https://alive2.llvm.org/ce/z/WUSvmV