SelectionDAG: Prefer to combine multiplication with less uses for fma
authorJingyue Wu <jingyue@google.com>
Tue, 11 Aug 2015 19:21:46 +0000 (19:21 +0000)
committerJingyue Wu <jingyue@google.com>
Tue, 11 Aug 2015 19:21:46 +0000 (19:21 +0000)
Summary:
For example:

  s6 = s0*s5;
  s2 = s6*s6 + s6;
  ...
  s4 = s6*s3;

We notice that it is possible for s2 is folded to fma (s0, s5, fmul (s6 s6)).
This only happens when Aggressive is true, otherwise hasOneUse() check
already prevents from folding the multiplication with more uses.

Test Plan: test/CodeGen/NVPTX/fma-assoc.ll

Patch by Xuetian Weng

Reviewers: hfinkel, apazos, jingyue, ohsallen, arsenm

Subscribers: arsenm, jholewinski, llvm-commits

Differential Revision: http://reviews.llvm.org/D11855

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244649 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
test/CodeGen/NVPTX/fma-assoc.ll

index 2c87d120cb7a50703a1d3894cf6eefeebc9a24c3..c4cbeb0076658eb8e66ad6c7db0fe18176532a23 100644 (file)
@@ -7426,6 +7426,14 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
   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 fc04c61dd691aa35dfc231528fd531ff5140bf39..80a08a86316c86f0d0ef7ca9e2412341943b8258 100644 (file)
@@ -23,3 +23,16 @@ define ptx_device double @t1_f64(double %x, double %y, double %z,
   %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
+}
+