Skip to content

Commit 0a1210e

Browse files
committed
[InstSimplify] try harder to fold fmul with 0.0 operand
https://alive2.llvm.org/ce/z/oShzr3 This was noted as a missing fold in D134876 (with additional examples based on issue #58046). I'm assuming that fmul with a zero operand is rare enough that the use of ValueTracking will not noticeably increase compile-time. This adjusts a PowerPC codegen test that was added with D88388 because it would get folded away and no longer provide coverage for the bug fix.
1 parent ab9a81f commit 0a1210e

File tree

4 files changed

+30
-33
lines changed

4 files changed

+30
-33
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -5333,9 +5333,16 @@ static Value *simplifyFMAFMul(Value *Op0, Value *Op1, FastMathFlags FMF,
53335333
if (match(Op1, m_FPOne()))
53345334
return Op0;
53355335

5336-
// X * 0.0 --> 0.0 (with nnan and nsz)
5337-
if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op1, m_AnyZeroFP()))
5338-
return ConstantFP::getNullValue(Op0->getType());
5336+
if (match(Op1, m_AnyZeroFP())) {
5337+
// X * 0.0 --> 0.0 (with nnan and nsz)
5338+
if (FMF.noNaNs() && FMF.noSignedZeros())
5339+
return ConstantFP::getNullValue(Op0->getType());
5340+
5341+
// +normal number * (-)0.0 --> (-)0.0
5342+
if (isKnownNeverInfinity(Op0, Q.TLI) && isKnownNeverNaN(Op0, Q.TLI) &&
5343+
SignBitMustBeZero(Op0, Q.TLI))
5344+
return Op1;
5345+
}
53395346

53405347
// sqrt(X) * sqrt(X) --> X, if we can:
53415348
// 1. Remove the intermediate rounding (reassociate).

llvm/test/CodeGen/PowerPC/pr47660.ll

+12-14
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,36 @@
66
; RUN: -mtriple=powerpc64-linux-gnu < %s | FileCheck \
77
; RUN: -check-prefix=CHECK-BE %s
88

9-
define dso_local i24 @_Z1f1c(i24 %g.coerce) local_unnamed_addr #0 {
9+
define i8 @_Z1f1c(i24 %x) #0 {
1010
; CHECK-LE-LABEL: _Z1f1c:
11-
; CHECK-LE: # %bb.0: # %entry
12-
; CHECK-LE-NEXT: clrlwi r3, r3, 24
13-
; CHECK-LE-NEXT: xxlxor f1, f1, f1
11+
; CHECK-LE: # %bb.0:
12+
; CHECK-LE-NEXT: clrlwi r3, r3, 8
1413
; CHECK-LE-NEXT: mtfprwz f0, r3
14+
; CHECK-LE-NEXT: addis r3, r2, .LCPI0_0@toc@ha
15+
; CHECK-LE-NEXT: lfd f1, .LCPI0_0@toc@l(r3)
1516
; CHECK-LE-NEXT: xscvuxddp f0, f0
1617
; CHECK-LE-NEXT: xsmuldp f0, f0, f1
1718
; CHECK-LE-NEXT: xscvdpsxws f0, f0
1819
; CHECK-LE-NEXT: mffprwz r3, f0
1920
; CHECK-LE-NEXT: blr
2021
;
2122
; CHECK-BE-LABEL: _Z1f1c:
22-
; CHECK-BE: # %bb.0: # %entry
23-
; CHECK-BE-NEXT: clrldi r3, r3, 56
23+
; CHECK-BE: # %bb.0:
24+
; CHECK-BE-NEXT: clrldi r3, r3, 40
2425
; CHECK-BE-NEXT: std r3, -16(r1)
2526
; CHECK-BE-NEXT: addis r3, r2, .LCPI0_0@toc@ha
2627
; CHECK-BE-NEXT: lfd f0, -16(r1)
27-
; CHECK-BE-NEXT: lfs f1, .LCPI0_0@toc@l(r3)
28+
; CHECK-BE-NEXT: lfd f1, .LCPI0_0@toc@l(r3)
2829
; CHECK-BE-NEXT: fcfid f0, f0
2930
; CHECK-BE-NEXT: fmul f0, f0, f1
3031
; CHECK-BE-NEXT: fctiwz f0, f0
3132
; CHECK-BE-NEXT: stfd f0, -8(r1)
3233
; CHECK-BE-NEXT: lwz r3, -4(r1)
3334
; CHECK-BE-NEXT: blr
34-
entry:
35-
%0 = and i24 %g.coerce, 255
36-
%conv1 = uitofp i24 %0 to double
37-
%mul = fmul double 0.000000e+00, %conv1
38-
%conv2 = fptoui double %mul to i8
39-
%retval.sroa.0.0.insert.ext = zext i8 %conv2 to i24
40-
ret i24 %retval.sroa.0.0.insert.ext
35+
%conv1 = uitofp i24 %x to double
36+
%mul = fmul double 0.1, %conv1
37+
%r = fptoui double %mul to i8
38+
ret i8 %r
4139
}
4240

4341
attributes #0 = { "use-soft-float"="false" }

llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll

+7-10
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,7 @@ define double @fmul_X_1(double %a) {
172172

173173
define half @fmul_nnan_ninf_nneg_0.0(i15 %x) {
174174
; CHECK-LABEL: @fmul_nnan_ninf_nneg_0.0(
175-
; CHECK-NEXT: [[F:%.*]] = uitofp i15 [[X:%.*]] to half
176-
; CHECK-NEXT: [[R:%.*]] = fmul half [[F]], 0xH0000
177-
; CHECK-NEXT: ret half [[R]]
175+
; CHECK-NEXT: ret half 0xH0000
178176
;
179177
%f = uitofp i15 %x to half
180178
%r = fmul half %f, 0.0
@@ -183,15 +181,15 @@ define half @fmul_nnan_ninf_nneg_0.0(i15 %x) {
183181

184182
define half @fmul_nnan_ninf_nneg_n0.0(i15 %x) {
185183
; CHECK-LABEL: @fmul_nnan_ninf_nneg_n0.0(
186-
; CHECK-NEXT: [[F:%.*]] = uitofp i15 [[X:%.*]] to half
187-
; CHECK-NEXT: [[R:%.*]] = fmul half [[F]], 0xH8000
188-
; CHECK-NEXT: ret half [[R]]
184+
; CHECK-NEXT: ret half 0xH8000
189185
;
190186
%f = uitofp i15 %x to half
191187
%r = fmul half %f, -0.0
192188
ret half %r
193189
}
194190

191+
; negative test - the int could be big enough to round to INF
192+
195193
define half @fmul_nnan_nneg_0.0(i16 %x) {
196194
; CHECK-LABEL: @fmul_nnan_nneg_0.0(
197195
; CHECK-NEXT: [[F:%.*]] = uitofp i16 [[X:%.*]] to half
@@ -205,17 +203,16 @@ define half @fmul_nnan_nneg_0.0(i16 %x) {
205203

206204
define double @fmul_nnan_ninf_nneg_n0.0_commute(i127 %x) {
207205
; CHECK-LABEL: @fmul_nnan_ninf_nneg_n0.0_commute(
208-
; CHECK-NEXT: [[F:%.*]] = uitofp i127 [[X:%.*]] to float
209-
; CHECK-NEXT: [[E:%.*]] = fpext float [[F]] to double
210-
; CHECK-NEXT: [[R:%.*]] = fmul double -0.000000e+00, [[E]]
211-
; CHECK-NEXT: ret double [[R]]
206+
; CHECK-NEXT: ret double -0.000000e+00
212207
;
213208
%f = uitofp i127 %x to float
214209
%e = fpext float %f to double
215210
%r = fmul double -0.0, %e
216211
ret double %r
217212
}
218213

214+
; negative test - the int could be big enough to round to INF
215+
219216
define double @fmul_nnan_ninf_nneg_0.0_commute(i128 %x) {
220217
; CHECK-LABEL: @fmul_nnan_ninf_nneg_0.0_commute(
221218
; CHECK-NEXT: [[F:%.*]] = uitofp i128 [[X:%.*]] to float

llvm/test/Transforms/InstSimplify/floating-point-compare.ll

+1-6
Original file line numberDiff line numberDiff line change
@@ -999,14 +999,9 @@ define <2 x i1> @known_positive_une_with_negative_constant_splat_vec(<2 x i32> %
999999
ret <2 x i1> %cmp
10001000
}
10011001

1002-
; TODO: This could fold to true.
10031002
define i1 @pr58046(i64 %arg) {
10041003
; CHECK-LABEL: @pr58046(
1005-
; CHECK-NEXT: [[FP:%.*]] = uitofp i64 [[ARG:%.*]] to double
1006-
; CHECK-NEXT: [[MUL:%.*]] = fmul double -0.000000e+00, [[FP]]
1007-
; CHECK-NEXT: [[DIV:%.*]] = fdiv double 1.000000e+00, [[MUL]]
1008-
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[DIV]], 0xFFF0000000000000
1009-
; CHECK-NEXT: ret i1 [[CMP]]
1004+
; CHECK-NEXT: ret i1 true
10101005
;
10111006
%fp = uitofp i64 %arg to double
10121007
%mul = fmul double -0.000000e+00, %fp

0 commit comments

Comments
 (0)