Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -7426,6 +7426,16 @@ bool Aggressive = TLI.enableAggressiveFMAFusion(VT); bool LookThroughFPExt = TLI.isFPExtFree(VT); + // if we have two choice trying to fold (fadd (fmul u, v), (fmul x, y)) anyway, prefer to + // fold the multiplication with less use. + if (Aggressive && N0.getOpcode() == ISD::FMUL && + N1.getOpcode() == ISD::FMUL) { + if (N0.getNode()->use_size() > N1.getNode()->use_size()) { + using std::swap; + 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,19 @@ %d = fadd double %c, %z ret double %d } + +define double @two_choice(double %val1, double %val2) #0 { +; CHECK-LABEL: .visible .entry two_choice +; 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 +} + +!nvvm.annotations = !{!0} + +!0 = !{double (double, double)* @two_choice, !"kernel", i32 1}