Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -10941,13 +10941,9 @@ } } - // fold (fsub A, (fneg B)) -> (fadd A, B) - if (isNegatibleForFree(N1, LegalOperations, TLI, &Options)) - return DAG.getNode(ISD::FADD, DL, VT, N0, - GetNegatedExpression(N1, DAG, LegalOperations), Flags); - // If 'unsafe math' is enabled, fold lots of things. - if (Options.UnsafeFPMath) { + if (Options.UnsafeFPMath || + (Flags.hasAllowReassociation() && Flags.hasNoSignedZeros())) { // (fsub x, (fadd x, y)) -> (fneg y) // (fsub x, (fadd y, x)) -> (fneg y) if (N1.getOpcode() == ISD::FADD) { @@ -10962,6 +10958,11 @@ } } + // fold (fsub A, (fneg B)) -> (fadd A, B) + if (isNegatibleForFree(N1, LegalOperations, TLI, &Options)) + return DAG.getNode(ISD::FADD, DL, VT, N0, + GetNegatedExpression(N1, DAG, LegalOperations), Flags); + // FSUB -> FMA combines: if (SDValue Fused = visitFSUBForFMACombine(N)) { AddToWorklist(Fused.getNode()); Index: test/CodeGen/X86/fp-fold.ll =================================================================== --- test/CodeGen/X86/fp-fold.ll +++ test/CodeGen/X86/fp-fold.ll @@ -89,12 +89,10 @@ } define float @fsub_neg_y(float %x, float %y) { -; UNSAFE-LABEL: fsub_neg_y: -; UNSAFE: # %bb.0: -; UNSAFE-NEXT: mulss {{.*}}(%rip), %xmm0 -; UNSAFE-NEXT: subss %xmm1, %xmm0 -; UNSAFE-NEXT: addss %xmm1, %xmm0 -; UNSAFE-NEXT: retq +; ANY-LABEL: fsub_neg_y: +; ANY: # %bb.0: +; ANY-NEXT: mulss {{.*}}(%rip), %xmm0 +; ANY-NEXT: retq %mul = fmul float %x, 5.000000e+00 %add = fadd float %mul, %y %r = fsub nsz reassoc float %y, %add