diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -5820,15 +5820,17 @@ // 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; } @@ -5865,8 +5867,9 @@ // 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. @@ -5877,8 +5880,9 @@ // 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; } @@ -5907,15 +5911,17 @@ // 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/llvm/test/CodeGen/PowerPC/fneg.ll b/llvm/test/CodeGen/PowerPC/fneg.ll --- a/llvm/test/CodeGen/PowerPC/fneg.ll +++ b/llvm/test/CodeGen/PowerPC/fneg.ll @@ -39,3 +39,20 @@ %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 +}