Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -10930,13 +10930,8 @@ } } - // 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()) { // (fsub x, (fadd x, y)) -> (fneg y) // (fsub x, (fadd y, x)) -> (fneg y) if (N1.getOpcode() == ISD::FADD) { @@ -10951,6 +10946,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 @@ -88,6 +88,21 @@ ret float %r } +define float @fsub_neg_y(float %x, float %y) { +; ANY-LABEL: fsub_neg_y: +; ANY: # %bb.0: +; ANY-NEXT: mulss %xmm1, %xmm0 +; ANY-NEXT: andps {{.*}}(%rip), %xmm0 +; ANY-NEXT: mulss {{.*}}(%rip), %xmm0 +; ANY-NEXT: retq + %mul1 = fmul float %x, %y + %abs = call float @llvm.fabs.f32(float %mul1) #1 + %mul2 = fmul float %abs, 5.000000e+00 + %add = fadd float %mul2, 1.0 + %r = fsub reassoc float 1.0, %add + ret float %r +} + define float @fsub_negzero(float %x) { ; STRICT-LABEL: fsub_negzero: ; STRICT: # %bb.0: @@ -153,3 +168,5 @@ %r = fmul reassoc float %mul, 4.0 ret float %r } + +declare float @llvm.fabs.f32(float) #1