diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -15079,12 +15079,14 @@ TargetLowering::NegatibleCost::Expensive; SDValue NegN0 = TLI.getNegatedExpression(N0, DAG, LegalOperations, ForCodeSize, CostN0); - SDValue NegN1 = - TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize, CostN1); - if (NegN0 && NegN1 && - (CostN0 == TargetLowering::NegatibleCost::Cheaper || - CostN1 == TargetLowering::NegatibleCost::Cheaper)) - return DAG.getNode(ISD::FMUL, DL, VT, NegN0, NegN1); + if (NegN0) { + HandleSDNode NegN0Handle(NegN0); + SDValue NegN1 = + TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize, CostN1); + if (NegN1 && (CostN0 == TargetLowering::NegatibleCost::Cheaper || + CostN1 == TargetLowering::NegatibleCost::Cheaper)) + return DAG.getNode(ISD::FMUL, DL, VT, NegN0, NegN1); + } // fold (fmul X, (select (fcmp X > 0.0), -1.0, 1.0)) -> (fneg (fabs X)) // fold (fmul X, (select (fcmp X > 0.0), 1.0, -1.0)) -> (fabs X) @@ -15170,12 +15172,14 @@ TargetLowering::NegatibleCost::Expensive; SDValue NegN0 = TLI.getNegatedExpression(N0, DAG, LegalOperations, ForCodeSize, CostN0); - SDValue NegN1 = - TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize, CostN1); - if (NegN0 && NegN1 && - (CostN0 == TargetLowering::NegatibleCost::Cheaper || - CostN1 == TargetLowering::NegatibleCost::Cheaper)) - return DAG.getNode(ISD::FMA, DL, VT, NegN0, NegN1, N2); + if (NegN0) { + HandleSDNode NegN0Handle(NegN0); + SDValue NegN1 = + TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize, CostN1); + if (NegN1 && (CostN0 == TargetLowering::NegatibleCost::Cheaper || + CostN1 == TargetLowering::NegatibleCost::Cheaper)) + return DAG.getNode(ISD::FMA, DL, VT, NegN0, NegN1, N2); + } // FIXME: use fast math flags instead of Options.UnsafeFPMath if (Options.UnsafeFPMath) { @@ -15473,12 +15477,14 @@ TargetLowering::NegatibleCost::Expensive; SDValue NegN0 = TLI.getNegatedExpression(N0, DAG, LegalOperations, ForCodeSize, CostN0); - SDValue NegN1 = - TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize, CostN1); - if (NegN0 && NegN1 && - (CostN0 == TargetLowering::NegatibleCost::Cheaper || - CostN1 == TargetLowering::NegatibleCost::Cheaper)) - return DAG.getNode(ISD::FDIV, SDLoc(N), VT, NegN0, NegN1); + if (NegN0) { + HandleSDNode NegN0Handle(NegN0); + SDValue NegN1 = + TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize, CostN1); + if (NegN1 && (CostN0 == TargetLowering::NegatibleCost::Cheaper || + CostN1 == TargetLowering::NegatibleCost::Cheaper)) + return DAG.getNode(ISD::FDIV, SDLoc(N), VT, NegN0, NegN1); + } return SDValue(); } diff --git a/llvm/test/CodeGen/X86/pr57658.ll b/llvm/test/CodeGen/X86/pr57658.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/pr57658.ll @@ -0,0 +1,21 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s + +define <2 x double> @f(<2 x double> %I) { +; CHECK-LABEL: f: +; CHECK: # %bb.0: # %BB +; CHECK-NEXT: movapd {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0] +; CHECK-NEXT: xorpd %xmm0, %xmm1 +; CHECK-NEXT: mulpd %xmm0, %xmm1 +; CHECK-NEXT: mulpd %xmm0, %xmm1 +; CHECK-NEXT: mulpd %xmm0, %xmm0 +; CHECK-NEXT: mulpd %xmm1, %xmm0 +; CHECK-NEXT: retq +BB: + %F = fneg <2 x double> %I + %B3 = fmul <2 x double> %I, %F + %B1 = fmul <2 x double> %F, %B3 + %B2 = fmul <2 x double> %F, %I + %B = fmul <2 x double> %B2, %B1 + ret <2 x double> %B +}