Skip to content

[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

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions llvm/lib/Analysis/InstructionSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5767,11 +5767,16 @@ 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 foldConstant(Instruction::FNeg, Op1, Q);
}
}

// sqrt(X) * sqrt(X) --> X, if we can:
Expand Down
44 changes: 44 additions & 0 deletions llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,50 @@ 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 <2 x float> @src_mul_zero_neg(<2 x float> nofpclass(inf nan pzero psub pnorm) %f) {
; CHECK-LABEL: @src_mul_zero_neg(
; CHECK-NEXT: ret <2 x float> <float -0.000000e+00, float -0.000000e+00>
;
%r = fmul <2 x float> <float 0.0, float 0.0>, %f
ret <2 x float> %r
}

define <2 x float> @src_mul_zero_and_nzero_neg(<2 x float> nofpclass(inf nan pzero psub pnorm) %f) {
; CHECK-LABEL: @src_mul_zero_and_nzero_neg(
; CHECK-NEXT: ret <2 x float> <float 0.000000e+00, float -0.000000e+00>
;
%r = fmul <2 x float> <float -0.0, float 0.0>, %f
ret <2 x float> %r
}


define float @src_muladd_zero_neg(float nofpclass(inf nan pzero psub pnorm) %f, float %add) {
; CHECK-LABEL: @src_muladd_zero_neg(
; 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)
Copy link
Contributor

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

Copy link
Contributor Author

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.

ret float %r
}

define float @src_fma_nzero_neg(float nofpclass(inf nan pzero psub pnorm) %f, float %add) {
; CHECK-LABEL: @src_fma_nzero_neg(
; CHECK-NEXT: [[R:%.*]] = call float @llvm.fma.f32(float -0.000000e+00, float [[F:%.*]], float [[ADD:%.*]])
; CHECK-NEXT: ret float [[R]]
;
%r = call float @llvm.fma.f32(float -0.0, float %f, float %add)
ret float %r
}

Copy link
Contributor

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

Copy link
Contributor Author

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.


; 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(
Expand Down