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,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)