[PATCH] D75982: [DAGCombine] Respect the uses when combine FMA for a*b+/-c*d

qshanz via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 11 20:30:44 PDT 2020


steven.zhang updated this revision to Diff 249821.
steven.zhang retitled this revision from "[DAGCombine] Respect the uses when combine FMA for a*b+/-c*d and add target hook if there uses are the same" to "[DAGCombine] Respect the uses when combine FMA for a*b+/-c*d".
steven.zhang edited the summary of this revision.
steven.zhang added a comment.

Remove the hook.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75982/new/

https://reviews.llvm.org/D75982

Files:
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/test/CodeGen/PowerPC/fma-precision.ll
  llvm/test/CodeGen/PowerPC/recipest.ll


Index: llvm/test/CodeGen/PowerPC/recipest.ll
===================================================================
--- llvm/test/CodeGen/PowerPC/recipest.ll
+++ llvm/test/CodeGen/PowerPC/recipest.ll
@@ -177,12 +177,11 @@
 ; CHECK-NEXT:    fmuls 1, 1, 0
 ; CHECK-NEXT:    fmadds 1, 1, 0, 4
 ; CHECK-NEXT:    fmuls 0, 0, 5
-; CHECK-NEXT:    fres 5, 2
+; CHECK-NEXT:    fmuls 0, 0, 1
+; CHECK-NEXT:    fres 1, 2
 ; CHECK-NEXT:    fmuls 4, 0, 1
-; CHECK-NEXT:    fmuls 4, 4, 5
-; CHECK-NEXT:    fmuls 2, 2, 4
-; CHECK-NEXT:    fmsubs 0, 0, 1, 2
-; CHECK-NEXT:    fmadds 0, 5, 0, 4
+; CHECK-NEXT:    fnmsubs 0, 2, 4, 0
+; CHECK-NEXT:    fmadds 0, 1, 0, 4
 ; CHECK-NEXT:    fmuls 1, 3, 0
 ; CHECK-NEXT:    blr
   %x = call fast float @llvm.sqrt.f32(float %a)
Index: llvm/test/CodeGen/PowerPC/fma-precision.ll
===================================================================
--- llvm/test/CodeGen/PowerPC/fma-precision.ll
+++ llvm/test/CodeGen/PowerPC/fma-precision.ll
@@ -5,10 +5,10 @@
 define double @fsub1(double %a, double %b, double %c, double %d)  {
 ; CHECK-LABEL: fsub1:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    xsmuldp 3, 4, 3
 ; CHECK-NEXT:    xsmuldp 0, 2, 1
-; CHECK-NEXT:    xsmsubadp 3, 2, 1
-; CHECK-NEXT:    xsmuldp 1, 0, 3
+; CHECK-NEXT:    fmr 1, 0
+; CHECK-NEXT:    xsnmsubadp 1, 4, 3
+; CHECK-NEXT:    xsmuldp 1, 0, 1
 ; CHECK-NEXT:    blr
 entry:
   %mul = fmul fast double %b, %a
Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -11898,19 +11898,43 @@
   };
 
   // fold (fsub (fmul x, y), z) -> (fma x, y, (fneg z))
-  if (isContractableFMUL(N0) && (Aggressive || N0->hasOneUse())) {
-    return DAG.getNode(PreferredFusedOpcode, SL, VT,
-                       N0.getOperand(0), N0.getOperand(1),
-                       DAG.getNode(ISD::FNEG, SL, VT, N1), Flags);
-  }
+  auto tryToFoldXYSubZ = [&](SDValue XY, SDValue Z) {
+    if (isContractableFMUL(XY) && (Aggressive || XY->hasOneUse())) {
+      return DAG.getNode(PreferredFusedOpcode, SL, VT, XY.getOperand(0),
+                         XY.getOperand(1), DAG.getNode(ISD::FNEG, SL, VT, Z),
+                         Flags);
+    }
+    return SDValue();
+  };
 
   // fold (fsub x, (fmul y, z)) -> (fma (fneg y), z, x)
   // Note: Commutes FSUB operands.
-  if (isContractableFMUL(N1) && (Aggressive || N1->hasOneUse())) {
-    return DAG.getNode(PreferredFusedOpcode, SL, VT,
-                       DAG.getNode(ISD::FNEG, SL, VT,
-                                   N1.getOperand(0)),
-                       N1.getOperand(1), N0, Flags);
+  auto tryToFoldXSubYZ = [&](SDValue X, SDValue YZ) {
+    if (isContractableFMUL(YZ) && (Aggressive || YZ->hasOneUse())) {
+      return DAG.getNode(PreferredFusedOpcode, SL, VT,
+                         DAG.getNode(ISD::FNEG, SL, VT, YZ.getOperand(0)),
+                         YZ.getOperand(1), X, Flags);
+    }
+    return SDValue();
+  };
+
+  // If we have two choices trying to fold (fsub (fmul u, v), (fmul x, y)),
+  // prefer to fold the multiply with fewer uses.
+  if (Aggressive && isContractableFMUL(N0) && isContractableFMUL(N1) &&
+      (N0.getNode()->use_size() > N1.getNode()->use_size())) {
+    // fold (fsub x, (fmul y, z)) -> (fma (fneg y), z, x)
+    if (SDValue V = tryToFoldXSubYZ(N0, N1))
+      return V;
+    // fold (fsub (fmul x, y), z) -> (fma x, y, (fneg z))
+    if (SDValue V = tryToFoldXYSubZ(N0, N1))
+      return V;
+  } else {
+    // fold (fsub (fmul x, y), z) -> (fma x, y, (fneg z))
+    if (SDValue V = tryToFoldXYSubZ(N0, N1))
+      return V;
+    // fold (fsub x, (fmul y, z)) -> (fma (fneg y), z, x)
+    if (SDValue V = tryToFoldXSubYZ(N0, N1))
+      return V;
   }
 
   // fold (fsub (fneg (fmul, x, y)), z) -> (fma (fneg x), y, (fneg z))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D75982.249821.patch
Type: text/x-patch
Size: 3897 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200312/977c0af4/attachment.bin>


More information about the llvm-commits mailing list