Skip to content

Commit 2ccbf3d

Browse files
committed
[SDAG] fold x * 0.0 at node creation time
In the motivating case from https://llvm.org/PR47517 we create a node that does not get constant folded before getNegatedExpression is attempted from some other node, and we crash. By moving the fold into SelectionDAG::simplifyFPBinop(), we get the constant fold sooner and avoid the problem.
1 parent 2c48dd7 commit 2ccbf3d

File tree

4 files changed

+26
-20
lines changed

4 files changed

+26
-20
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13040,13 +13040,6 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
1304013040
if (SDValue NewSel = foldBinOpIntoSelect(N))
1304113041
return NewSel;
1304213042

13043-
if ((Options.NoNaNsFPMath && Options.NoSignedZerosFPMath) ||
13044-
(Flags.hasNoNaNs() && Flags.hasNoSignedZeros())) {
13045-
// fold (fmul A, 0) -> 0
13046-
if (N1CFP && N1CFP->isZero())
13047-
return N1;
13048-
}
13049-
1305013043
if (Options.UnsafeFPMath || Flags.hasAllowReassociation()) {
1305113044
// fmul (fmul X, C1), C2 -> fmul X, C1 * C2
1305213045
if (isConstantFPBuildVectorOrConstantFP(N1) &&

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7475,6 +7475,11 @@ SDValue SelectionDAG::simplifyFPBinop(unsigned Opcode, SDValue X, SDValue Y,
74757475
if (YC->getValueAPF().isExactlyValue(1.0))
74767476
return X;
74777477

7478+
// X * 0.0 --> 0.0
7479+
if (Opcode == ISD::FMUL && Flags.hasNoNaNs() && Flags.hasNoSignedZeros())
7480+
if (YC->getValueAPF().isZero())
7481+
return getConstantFP(0.0, SDLoc(Y), Y.getValueType());
7482+
74787483
return SDValue();
74797484
}
74807485

llvm/test/CodeGen/ARM/softfp-constant-comparison.ll

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,13 @@ target triple = "thumbv7em-arm-none-eabi"
99
define hidden void @fn1() nounwind #0 {
1010
; CHECK-LABEL: fn1:
1111
; CHECK: @ %bb.0: @ %entry
12-
; CHECK-NEXT: .save {r7, lr}
13-
; CHECK-NEXT: push {r7, lr}
14-
; CHECK-NEXT: vldr d0, .LCPI0_0
15-
; CHECK-NEXT: vmov r0, r1, d0
16-
; CHECK-NEXT: mov r2, r0
17-
; CHECK-NEXT: mov r3, r1
18-
; CHECK-NEXT: bl __aeabi_dcmpeq
12+
; CHECK-NEXT: movs r0, #1
1913
; CHECK-NEXT: cbnz r0, .LBB0_2
2014
; CHECK-NEXT: b .LBB0_1
2115
; CHECK-NEXT: .LBB0_1: @ %land.rhs
2216
; CHECK-NEXT: b .LBB0_2
2317
; CHECK-NEXT: .LBB0_2: @ %land.end
24-
; CHECK-NEXT: pop {r7, pc}
25-
; CHECK-NEXT: .p2align 3
26-
; CHECK-NEXT: @ %bb.3:
27-
; CHECK-NEXT: .LCPI0_0:
28-
; CHECK-NEXT: .long 0 @ double 0
29-
; CHECK-NEXT: .long 0
18+
; CHECK-NEXT: bx lr
3019
entry:
3120
%0 = load i32, i32* @a, align 4
3221
%conv = sitofp i32 %0 to double

llvm/test/CodeGen/X86/fmul-combines.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,22 @@ define <4 x float> @fmul_fneg_fneg_v4f32(<4 x float> %x, <4 x float> %y) {
261261
%mul = fmul <4 x float> %x.neg, %y.neg
262262
ret <4 x float> %mul
263263
}
264+
265+
; PR47517 - this could crash if we create 'fmul x, 0.0' nodes
266+
; that do not constant fold in a particular order.
267+
268+
define float @getNegatedExpression_crash(float* %p) {
269+
; CHECK-LABEL: getNegatedExpression_crash:
270+
; CHECK: # %bb.0:
271+
; CHECK-NEXT: movl $0, (%rdi)
272+
; CHECK-NEXT: xorps %xmm0, %xmm0
273+
; CHECK-NEXT: retq
274+
store float 0.0, float* %p, align 1
275+
%real = load float, float* %p, align 1
276+
%r2 = fmul fast float %real, %real
277+
%t1 = fmul fast float %real, 42.0
278+
%t2 = fmul fast float %real, %t1
279+
%mul_ac56 = fmul fast float %t2, %t1
280+
%mul_ac72 = fmul fast float %r2, %mul_ac56
281+
ret float %mul_ac72
282+
}

0 commit comments

Comments
 (0)