1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[DAGCombine] Don't delete the node if it has uses immediately

This is the follow up patch for https://reviews.llvm.org/D86183 as we miss to delete the node if NegX == NegY, which has use after we create the node.
```
    if (NegX && (CostX <= CostY)) {
      Cost = std::min(CostX, CostZ);
      RemoveDeadNode(NegY);
      return DAG.getNode(Opcode, DL, VT, NegX, Y, NegZ, Flags);  #<-- NegY is used here if NegY == NegX.
    }
```

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D86689

(cherry picked from commit deb4b2580715810ecd5cb7eefa5ffbe65e5eedc8)
This commit is contained in:
QingShan Zhang 2020-08-28 15:21:47 +00:00 committed by Hans Wennborg
parent 62d099a705
commit 9e52bd71bf
2 changed files with 29 additions and 6 deletions

View File

@ -5809,15 +5809,17 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
// Negate the X if its cost is less or equal than Y. // Negate the X if its cost is less or equal than Y.
if (NegX && (CostX <= CostY)) { if (NegX && (CostX <= CostY)) {
Cost = CostX; Cost = CostX;
SDValue N = DAG.getNode(ISD::FSUB, DL, VT, NegX, Y, Flags);
RemoveDeadNode(NegY); RemoveDeadNode(NegY);
return DAG.getNode(ISD::FSUB, DL, VT, NegX, Y, Flags); return N;
} }
// Negate the Y if it is not expensive. // Negate the Y if it is not expensive.
if (NegY) { if (NegY) {
Cost = CostY; Cost = CostY;
SDValue N = DAG.getNode(ISD::FSUB, DL, VT, NegY, X, Flags);
RemoveDeadNode(NegX); RemoveDeadNode(NegX);
return DAG.getNode(ISD::FSUB, DL, VT, NegY, X, Flags); return N;
} }
break; break;
} }
@ -5854,8 +5856,9 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
// Negate the X if its cost is less or equal than Y. // Negate the X if its cost is less or equal than Y.
if (NegX && (CostX <= CostY)) { if (NegX && (CostX <= CostY)) {
Cost = CostX; Cost = CostX;
SDValue N = DAG.getNode(Opcode, DL, VT, NegX, Y, Flags);
RemoveDeadNode(NegY); RemoveDeadNode(NegY);
return DAG.getNode(Opcode, DL, VT, NegX, Y, Flags); return N;
} }
// Ignore X * 2.0 because that is expected to be canonicalized to X + X. // Ignore X * 2.0 because that is expected to be canonicalized to X + X.
@ -5866,8 +5869,9 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
// Negate the Y if it is not expensive. // Negate the Y if it is not expensive.
if (NegY) { if (NegY) {
Cost = CostY; Cost = CostY;
SDValue N = DAG.getNode(Opcode, DL, VT, X, NegY, Flags);
RemoveDeadNode(NegX); RemoveDeadNode(NegX);
return DAG.getNode(Opcode, DL, VT, X, NegY, Flags); return N;
} }
break; break;
} }
@ -5896,15 +5900,17 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
// Negate the X if its cost is less or equal than Y. // Negate the X if its cost is less or equal than Y.
if (NegX && (CostX <= CostY)) { if (NegX && (CostX <= CostY)) {
Cost = std::min(CostX, CostZ); Cost = std::min(CostX, CostZ);
SDValue N = DAG.getNode(Opcode, DL, VT, NegX, Y, NegZ, Flags);
RemoveDeadNode(NegY); RemoveDeadNode(NegY);
return DAG.getNode(Opcode, DL, VT, NegX, Y, NegZ, Flags); return N;
} }
// Negate the Y if it is not expensive. // Negate the Y if it is not expensive.
if (NegY) { if (NegY) {
Cost = std::min(CostY, CostZ); Cost = std::min(CostY, CostZ);
SDValue N = DAG.getNode(Opcode, DL, VT, X, NegY, NegZ, Flags);
RemoveDeadNode(NegX); RemoveDeadNode(NegX);
return DAG.getNode(Opcode, DL, VT, X, NegY, NegZ, Flags); return N;
} }
break; break;
} }

View File

@ -39,3 +39,20 @@ define float @fma_fneg_fsub(float %x, float %y0, float %y1, float %z) {
%r = call float @llvm.fmuladd.f32(float %negx, float %negy, float %z) %r = call float @llvm.fmuladd.f32(float %negx, float %negy, float %z)
ret float %r ret float %r
} }
; Verify that we didn't hit assertion for this case.
define double @fneg_no_ice(float %x) {
; CHECK-LABEL: fneg_no_ice:
; CHECK: # %bb.0:
; CHECK-NEXT: lis r3, .LCPI3_0@ha
; CHECK-NEXT: lfs f0, .LCPI3_0@l(r3)
; CHECK-NEXT: fsubs f0, f0, f1
; CHECK-NEXT: fmul f1, f0, f0
; CHECK-NEXT: fmul f1, f0, f1
; CHECK-NEXT: blr
%y = fsub fast float 1.0, %x
%e = fpext float %y to double
%e2 = fmul double %e, %e
%e3 = fmul double %e, %e2
ret double %e3
}