diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 94cb6da3d69..819e608c689 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -5809,15 +5809,17 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, // Negate the X if its cost is less or equal than Y. if (NegX && (CostX <= CostY)) { Cost = CostX; + SDValue N = DAG.getNode(ISD::FSUB, DL, VT, NegX, Y, Flags); RemoveDeadNode(NegY); - return DAG.getNode(ISD::FSUB, DL, VT, NegX, Y, Flags); + return N; } // Negate the Y if it is not expensive. if (NegY) { Cost = CostY; + SDValue N = DAG.getNode(ISD::FSUB, DL, VT, NegY, X, Flags); RemoveDeadNode(NegX); - return DAG.getNode(ISD::FSUB, DL, VT, NegY, X, Flags); + return N; } break; } @@ -5854,8 +5856,9 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, // Negate the X if its cost is less or equal than Y. if (NegX && (CostX <= CostY)) { Cost = CostX; + SDValue N = DAG.getNode(Opcode, DL, VT, NegX, Y, Flags); 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. @@ -5866,8 +5869,9 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, // Negate the Y if it is not expensive. if (NegY) { Cost = CostY; + SDValue N = DAG.getNode(Opcode, DL, VT, X, NegY, Flags); RemoveDeadNode(NegX); - return DAG.getNode(Opcode, DL, VT, X, NegY, Flags); + return N; } break; } @@ -5896,15 +5900,17 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, // Negate the X if its cost is less or equal than Y. if (NegX && (CostX <= CostY)) { Cost = std::min(CostX, CostZ); + SDValue N = DAG.getNode(Opcode, DL, VT, NegX, Y, NegZ, Flags); RemoveDeadNode(NegY); - return DAG.getNode(Opcode, DL, VT, NegX, Y, NegZ, Flags); + return N; } // Negate the Y if it is not expensive. if (NegY) { Cost = std::min(CostY, CostZ); + SDValue N = DAG.getNode(Opcode, DL, VT, X, NegY, NegZ, Flags); RemoveDeadNode(NegX); - return DAG.getNode(Opcode, DL, VT, X, NegY, NegZ, Flags); + return N; } break; } diff --git a/test/CodeGen/PowerPC/fneg.ll b/test/CodeGen/PowerPC/fneg.ll index 328ffecd176..aea34e216d6 100644 --- a/test/CodeGen/PowerPC/fneg.ll +++ b/test/CodeGen/PowerPC/fneg.ll @@ -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) 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 +}