Skip to content

Commit b78e5de

Browse files
ecneliseszmodem
authored andcommitted
[SelectionDAG] Check any use of negation result before removal
2508ef0 fixed a bug about constant removal in negation. But after sanitizing check I found there's still some issue about it so it's reverted. Temporary nodes will be removed if useless in negation. Before the removal, they'd be checked if any other nodes used it. So the removal was moved after getNode. However in rare cases the node to be removed is the same as result of getNode. We missed that and will be fixed by this patch. Reviewed By: steven.zhang Differential Revision: https://reviews.llvm.org/D87614 (cherry picked from commit a2fb544)
1 parent 4fe4e35 commit b78e5de

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5751,8 +5751,10 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
57515751

57525752
// If we already have the use of the negated floating constant, it is free
57535753
// to negate it even it has multiple uses.
5754-
if (!Op.hasOneUse() && CFP.use_empty())
5754+
if (!Op.hasOneUse() && CFP.use_empty()) {
5755+
RemoveDeadNode(CFP);
57555756
break;
5757+
}
57565758
Cost = NegatibleCost::Neutral;
57575759
return CFP;
57585760
}
@@ -5810,15 +5812,17 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
58105812
if (NegX && (CostX <= CostY)) {
58115813
Cost = CostX;
58125814
SDValue N = DAG.getNode(ISD::FSUB, DL, VT, NegX, Y, Flags);
5813-
RemoveDeadNode(NegY);
5815+
if (NegY != N)
5816+
RemoveDeadNode(NegY);
58145817
return N;
58155818
}
58165819

58175820
// Negate the Y if it is not expensive.
58185821
if (NegY) {
58195822
Cost = CostY;
58205823
SDValue N = DAG.getNode(ISD::FSUB, DL, VT, NegY, X, Flags);
5821-
RemoveDeadNode(NegX);
5824+
if (NegX != N)
5825+
RemoveDeadNode(NegX);
58225826
return N;
58235827
}
58245828
break;
@@ -5857,7 +5861,8 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
58575861
if (NegX && (CostX <= CostY)) {
58585862
Cost = CostX;
58595863
SDValue N = DAG.getNode(Opcode, DL, VT, NegX, Y, Flags);
5860-
RemoveDeadNode(NegY);
5864+
if (NegY != N)
5865+
RemoveDeadNode(NegY);
58615866
return N;
58625867
}
58635868

@@ -5870,7 +5875,8 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
58705875
if (NegY) {
58715876
Cost = CostY;
58725877
SDValue N = DAG.getNode(Opcode, DL, VT, X, NegY, Flags);
5873-
RemoveDeadNode(NegX);
5878+
if (NegX != N)
5879+
RemoveDeadNode(NegX);
58745880
return N;
58755881
}
58765882
break;
@@ -5901,15 +5907,17 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
59015907
if (NegX && (CostX <= CostY)) {
59025908
Cost = std::min(CostX, CostZ);
59035909
SDValue N = DAG.getNode(Opcode, DL, VT, NegX, Y, NegZ, Flags);
5904-
RemoveDeadNode(NegY);
5910+
if (NegY != N)
5911+
RemoveDeadNode(NegY);
59055912
return N;
59065913
}
59075914

59085915
// Negate the Y if it is not expensive.
59095916
if (NegY) {
59105917
Cost = std::min(CostY, CostZ);
59115918
SDValue N = DAG.getNode(Opcode, DL, VT, X, NegY, NegZ, Flags);
5912-
RemoveDeadNode(NegX);
5919+
if (NegX != N)
5920+
RemoveDeadNode(NegX);
59135921
return N;
59145922
}
59155923
break;

llvm/test/CodeGen/X86/pr47517.ll

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple x86_64 < %s | FileCheck %s
3+
4+
; To ensure unused floating point constant is correctly removed
5+
define float @test(float %src, float* %p) {
6+
; CHECK-LABEL: test:
7+
; CHECK: # %bb.0: # %entry
8+
; CHECK-NEXT: movq $0, (%rdi)
9+
; CHECK-NEXT: xorps %xmm0, %xmm0
10+
; CHECK-NEXT: retq
11+
entry:
12+
%a0 = getelementptr inbounds float, float* %p, i32 0
13+
%a1 = getelementptr inbounds float, float* %p, i32 1
14+
store float 0.000000e+00, float* %a0
15+
store float 0.000000e+00, float* %a1
16+
%zero = load float, float* %a0
17+
%fmul1 = fmul fast float %zero, %src
18+
%fadd1 = fadd fast float %fmul1, %zero
19+
%fmul2 = fmul fast float %fadd1, 2.000000e+00
20+
%fmul3 = fmul fast float %fmul2, %fmul2
21+
%fmul4 = fmul fast float %fmul2, 2.000000e+00
22+
%fadd2 = fadd fast float %fmul4, -3.000000e+00
23+
%fmul5 = fmul fast float %fadd2, %fmul2
24+
%fadd3 = fadd fast float %fmul2, %src
25+
%fadd4 = fadd fast float %fadd3, %fmul5
26+
%fmul6 = fmul fast float %fmul3, %fadd4
27+
ret float %fmul6
28+
}

0 commit comments

Comments
 (0)