Skip to content

Commit a2fb544

Browse files
committed
[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
1 parent b056292 commit a2fb544

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

+15-7
Original file line numberDiff line numberDiff line change
@@ -5773,8 +5773,10 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
57735773

57745774
// If we already have the use of the negated floating constant, it is free
57755775
// to negate it even it has multiple uses.
5776-
if (!Op.hasOneUse() && CFP.use_empty())
5776+
if (!Op.hasOneUse() && CFP.use_empty()) {
5777+
RemoveDeadNode(CFP);
57775778
break;
5779+
}
57785780
Cost = NegatibleCost::Neutral;
57795781
return CFP;
57805782
}
@@ -5832,15 +5834,17 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
58325834
if (NegX && (CostX <= CostY)) {
58335835
Cost = CostX;
58345836
SDValue N = DAG.getNode(ISD::FSUB, DL, VT, NegX, Y, Flags);
5835-
RemoveDeadNode(NegY);
5837+
if (NegY != N)
5838+
RemoveDeadNode(NegY);
58365839
return N;
58375840
}
58385841

58395842
// Negate the Y if it is not expensive.
58405843
if (NegY) {
58415844
Cost = CostY;
58425845
SDValue N = DAG.getNode(ISD::FSUB, DL, VT, NegY, X, Flags);
5843-
RemoveDeadNode(NegX);
5846+
if (NegX != N)
5847+
RemoveDeadNode(NegX);
58445848
return N;
58455849
}
58465850
break;
@@ -5879,7 +5883,8 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
58795883
if (NegX && (CostX <= CostY)) {
58805884
Cost = CostX;
58815885
SDValue N = DAG.getNode(Opcode, DL, VT, NegX, Y, Flags);
5882-
RemoveDeadNode(NegY);
5886+
if (NegY != N)
5887+
RemoveDeadNode(NegY);
58835888
return N;
58845889
}
58855890

@@ -5892,7 +5897,8 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
58925897
if (NegY) {
58935898
Cost = CostY;
58945899
SDValue N = DAG.getNode(Opcode, DL, VT, X, NegY, Flags);
5895-
RemoveDeadNode(NegX);
5900+
if (NegX != N)
5901+
RemoveDeadNode(NegX);
58965902
return N;
58975903
}
58985904
break;
@@ -5923,15 +5929,17 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
59235929
if (NegX && (CostX <= CostY)) {
59245930
Cost = std::min(CostX, CostZ);
59255931
SDValue N = DAG.getNode(Opcode, DL, VT, NegX, Y, NegZ, Flags);
5926-
RemoveDeadNode(NegY);
5932+
if (NegY != N)
5933+
RemoveDeadNode(NegY);
59275934
return N;
59285935
}
59295936

59305937
// Negate the Y if it is not expensive.
59315938
if (NegY) {
59325939
Cost = std::min(CostY, CostZ);
59335940
SDValue N = DAG.getNode(Opcode, DL, VT, X, NegY, NegZ, Flags);
5934-
RemoveDeadNode(NegX);
5941+
if (NegX != N)
5942+
RemoveDeadNode(NegX);
59355943
return N;
59365944
}
59375945
break;

llvm/test/CodeGen/X86/pr47517.ll

+28
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)