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,14 +5820,16 @@ // Negate the X if its cost is less or equal than Y. if (NegX && (CostX <= CostY)) { Cost = CostX; - RemoveDeadNode(NegY); + if (NegX != NegY) + RemoveDeadNode(NegY); return DAG.getNode(ISD::FSUB, DL, VT, NegX, Y, Flags); } // Negate the Y if it is not expensive. if (NegY) { Cost = CostY; - RemoveDeadNode(NegX); + if (NegX != NegY) + RemoveDeadNode(NegX); return DAG.getNode(ISD::FSUB, DL, VT, NegY, X, Flags); } break; @@ -5865,7 +5867,8 @@ // Negate the X if its cost is less or equal than Y. if (NegX && (CostX <= CostY)) { Cost = CostX; - RemoveDeadNode(NegY); + if (NegX != NegY) + RemoveDeadNode(NegY); return DAG.getNode(Opcode, DL, VT, NegX, Y, Flags); } @@ -5877,7 +5880,8 @@ // Negate the Y if it is not expensive. if (NegY) { Cost = CostY; - RemoveDeadNode(NegX); + if (NegX != NegY) + RemoveDeadNode(NegX); return DAG.getNode(Opcode, DL, VT, X, NegY, Flags); } break; @@ -5907,14 +5911,16 @@ // Negate the X if its cost is less or equal than Y. if (NegX && (CostX <= CostY)) { Cost = std::min(CostX, CostZ); - RemoveDeadNode(NegY); + if (NegX != NegY) + RemoveDeadNode(NegY); return DAG.getNode(Opcode, DL, VT, NegX, Y, NegZ, Flags); } // Negate the Y if it is not expensive. if (NegY) { Cost = std::min(CostY, CostZ); - RemoveDeadNode(NegX); + if (NegX != NegY) + RemoveDeadNode(NegX); return DAG.getNode(Opcode, DL, VT, X, NegY, NegZ, Flags); } 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,28 @@ %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 void @fneg_no_ice() { +; CHECK-LABEL: fneg_no_ice: +; CHECK: # %bb.0: +; CHECK-NEXT: lfs f0, 0(r3) +; CHECK-NEXT: lis r3, .LCPI3_0@ha +; CHECK-NEXT: lfs f1, .LCPI3_0@l(r3) +; CHECK-NEXT: fsubs f0, f1, f0 +; CHECK-NEXT: fmul f1, f0, f0 +; CHECK-NEXT: fmul f0, f0, f1 +; CHECK-NEXT: frsp f0, f0 +; CHECK-NEXT: stfs f0, 0(r3) +; CHECK-NEXT: blr + %_val_rw_ = load float, float* undef, align 4 + %_val_w_ = load float, float* undef, align 4 + %_sub_tmp = fsub fast float 1.000000e+00, %_val_w_ + %_conv25 = fpext float %_sub_tmp to double + %_expi_result = call fast double @llvm.powi.f64(double %_conv25, i32 3) + %_conv26 = fptrunc double %_expi_result to float + store float %_conv26, float* undef, align 4 + ret void +} + +declare double @llvm.powi.f64(double, i32)