Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -7426,6 +7426,14 @@ bool Aggressive = TLI.enableAggressiveFMAFusion(VT); bool LookThroughFPExt = TLI.isFPExtFree(VT); + // If we have two choices trying to fold (fadd (fmul u, v), (fmul x, y)), + // prefer to fold the multiply with fewer uses. + if (Aggressive && N0.getOpcode() == ISD::FMUL && + N1.getOpcode() == ISD::FMUL) { + if (N0.getNode()->use_size() > N1.getNode()->use_size()) + std::swap(N0, N1); + } + // fold (fadd (fmul x, y), z) -> (fma x, y, z) if (N0.getOpcode() == ISD::FMUL && (Aggressive || N0->hasOneUse())) { Index: test/CodeGen/NVPTX/fma-assoc.ll =================================================================== --- test/CodeGen/NVPTX/fma-assoc.ll +++ test/CodeGen/NVPTX/fma-assoc.ll @@ -23,3 +23,16 @@ %d = fadd double %c, %z ret double %d } + +define double @two_choices(double %val1, double %val2) { +; CHECK-LABEL: two_choices( +; CHECK: mul.f64 +; CHECK-NOT: mul.f64 +; CHECK: fma.rn.f64 + %1 = fmul double %val1, %val2 + %2 = fmul double %1, %1 + %3 = fadd double %1, %2 + + ret double %3 +} +