generalize binop reassociation; NFC
authorSanjay Patel <spatel@rotateright.com>
Wed, 29 Apr 2015 22:30:02 +0000 (22:30 +0000)
committerSanjay Patel <spatel@rotateright.com>
Wed, 29 Apr 2015 22:30:02 +0000 (22:30 +0000)
Move the fold introduced in r236031:
http://reviews.llvm.org/rL236031

to its own helper function, so we can use it for other binops.

This is a preliminary step before partially solving:
https://llvm.org/bugs/show_bug.cgi?id=21768
https://llvm.org/bugs/show_bug.cgi?id=23116

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

lib/CodeGen/SelectionDAG/DAGCombiner.cpp

index 5a9b49d7761e271fe3015dd4fc61f962f2cfeb43..2a9f8e1d304dcf83f4fc10f124e79fa7dd84e299 100644 (file)
@@ -7647,6 +7647,33 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
   return SDValue();
 }
 
+static SDValue ReassociateBinops(SDNode *N, SelectionDAG &DAG) {
+  assert(N->getNumOperands() == 2 && "Invalid node for binop reassociation");
+  SDValue N0 = N->getOperand(0);
+  SDValue N1 = N->getOperand(1);
+  EVT VT = N->getValueType(0);
+  SDLoc DL(N);
+  unsigned Opcode = N->getOpcode();
+
+  // Canonicalize chains of this operation to LHS to allow the following fold.
+  if (N0.getOpcode() != Opcode && N1.getOpcode() == Opcode)
+    return DAG.getNode(Opcode, DL, VT, N1, N0);
+  
+  // Convert a chain of 3 dependent operations into 2 independent operations
+  // and 1 dependent operation:
+  //  (op N0: (op N00: (op z, w), N01: y), N1: x) ->
+  //  (op N00: (op z, w), (op N1: x, N01: y))
+  if (N0.getOpcode() == Opcode && N0.hasOneUse() && N1.getOpcode() != Opcode) {
+    SDValue N00 = N0.getOperand(0);
+    if (N00.getOpcode() == Opcode) {
+      SDValue N01 = N0.getOperand(1);
+      SDValue NewOp = DAG.getNode(Opcode, DL, VT, N1, N01);
+      return DAG.getNode(Opcode, DL, VT, N00, NewOp);
+    }
+  }
+  return SDValue();
+}
+
 SDValue DAGCombiner::visitFADD(SDNode *N) {
   SDValue N0 = N->getOperand(0);
   SDValue N1 = N->getOperand(1);
@@ -7781,24 +7808,10 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
                            N0.getOperand(0), DAG.getConstantFP(4.0, DL, VT));
       }
     }
-
-    // Canonicalize chains of adds to LHS to simplify the following transform.
-    if (N0.getOpcode() != ISD::FADD && N1.getOpcode() == ISD::FADD)
-      return DAG.getNode(ISD::FADD, DL, VT, N1, N0);
     
-    // Convert a chain of 3 dependent operations into 2 independent operations
-    // and 1 dependent operation:
-    //  (fadd N0: (fadd N00: (fadd z, w), N01: y), N1: x) ->
-    //  (fadd N00: (fadd z, w), (fadd N1: x, N01: y))
-    if (N0.getOpcode() == ISD::FADD &&  N0.hasOneUse() &&
-        N1.getOpcode() != ISD::FADD) {
-      SDValue N00 = N0.getOperand(0);
-      if (N00.getOpcode() == ISD::FADD) {
-        SDValue N01 = N0.getOperand(1);
-        SDValue NewAdd = DAG.getNode(ISD::FADD, DL, VT, N1, N01);
-        return DAG.getNode(ISD::FADD, DL, VT, N00, NewAdd);
-      }
-    }
+    if (SDValue Reassociated = ReassociateBinops(N, DAG))
+      return Reassociated;
+
   } // enable-unsafe-fp-math
 
   // FADD -> FMA combines: