[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp SelectionDAG.cpp

Nate Begeman natebegeman at mac.com
Fri Sep 9 12:50:03 PDT 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

DAGCombiner.cpp updated: 1.9 -> 1.10
SelectionDAG.cpp updated: 1.189 -> 1.190
---
Log message:

Last round of 2-node folds from SD.cpp.  Will  move on to 3 node ops such
as setcc and select next.


---
Diffs of the changes:  (+107 -2)

 DAGCombiner.cpp  |  103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 SelectionDAG.cpp |    6 ++-
 2 files changed, 107 insertions(+), 2 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.9 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.10
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.9	Thu Sep  8 15:18:10 2005
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp	Fri Sep  9 14:49:52 2005
@@ -574,6 +574,7 @@
 SDOperand DAGCombiner::visitAND(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
   SDOperand N1 = N->getOperand(1);
+  SDOperand LL, LR, RL, RR, CC0, CC1;
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
   MVT::ValueType VT = N1.getValueType();
@@ -620,12 +621,60 @@
     if (ConstantSDNode *ORI = dyn_cast<ConstantSDNode>(N0.getOperand(1)))
       if ((ORI->getValue() & N1C->getValue()) == N1C->getValue())
         return N1;
+  // fold (and (setcc x), (setcc y)) -> (setcc (and x, y))
+  if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){
+    ISD::CondCode Op0 = cast<CondCodeSDNode>(CC0)->get();
+    ISD::CondCode Op1 = cast<CondCodeSDNode>(CC1)->get();
+    
+    if (LR == RR && isa<ConstantSDNode>(LR) && Op0 == Op1 &&
+        MVT::isInteger(LL.getValueType())) {
+      // fold (X == 0) & (Y == 0) -> (X|Y == 0)
+      if (cast<ConstantSDNode>(LR)->getValue() == 0 && Op1 == ISD::SETEQ) {
+        SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL);
+        WorkList.push_back(ORNode.Val);
+        return DAG.getSetCC(VT, ORNode, LR, Op1);
+      }
+      // fold (X == -1) & (Y == -1) -> (X&Y == -1)
+      if (cast<ConstantSDNode>(LR)->isAllOnesValue() && Op1 == ISD::SETEQ) {
+        SDOperand ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL);
+        WorkList.push_back(ANDNode.Val);
+        return DAG.getSetCC(VT, ANDNode, LR, Op1);
+      }
+      // fold (X >  -1) & (Y >  -1) -> (X|Y > -1)
+      if (cast<ConstantSDNode>(LR)->isAllOnesValue() && Op1 == ISD::SETGT) {
+        SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL);
+        WorkList.push_back(ORNode.Val);
+        return DAG.getSetCC(VT, ORNode, LR, Op1);
+      }
+    }
+    // canonicalize equivalent to ll == rl
+    if (LL == RR && LR == RL) {
+      Op1 = ISD::getSetCCSwappedOperands(Op1);
+      std::swap(RL, RR);
+    }
+    if (LL == RL && LR == RR) {
+      bool isInteger = MVT::isInteger(LL.getValueType());
+      ISD::CondCode Result = ISD::getSetCCAndOperation(Op0, Op1, isInteger);
+      if (Result != ISD::SETCC_INVALID)
+        return DAG.getSetCC(N0.getValueType(), LL, LR, Result);
+    }
+  }
+  // fold (and (zext x), (zext y)) -> (zext (and x, y))
+  if (N0.getOpcode() == ISD::ZERO_EXTEND && 
+      N1.getOpcode() == ISD::ZERO_EXTEND &&
+      N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
+    SDOperand ANDNode = DAG.getNode(ISD::AND, N0.getOperand(0).getValueType(),
+                                    N0.getOperand(0), N1.getOperand(0));
+    WorkList.push_back(ANDNode.Val);
+    return DAG.getNode(ISD::ZERO_EXTEND, VT, ANDNode);
+  }
   return SDOperand();
 }
 
 SDOperand DAGCombiner::visitOR(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
   SDOperand N1 = N->getOperand(1);
+  SDOperand LL, LR, RL, RR, CC0, CC1;
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
   MVT::ValueType VT = N1.getValueType();
@@ -661,6 +710,51 @@
       return DAG.getNode(ISD::OR, VT, N0.getOperand(0),
                          DAG.getConstant(N1C->getValue()|N01C->getValue(), VT));
   }
+  // fold (or (setcc x), (setcc y)) -> (setcc (or x, y))
+  if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){
+    ISD::CondCode Op0 = cast<CondCodeSDNode>(CC0)->get();
+    ISD::CondCode Op1 = cast<CondCodeSDNode>(CC1)->get();
+    
+    if (LR == RR && isa<ConstantSDNode>(LR) && Op0 == Op1 &&
+        MVT::isInteger(LL.getValueType())) {
+      // fold (X != 0) | (Y != 0) -> (X|Y != 0)
+      // fold (X <  0) | (Y <  0) -> (X|Y < 0)
+      if (cast<ConstantSDNode>(LR)->getValue() == 0 && 
+          (Op1 == ISD::SETNE || Op1 == ISD::SETLT)) {
+        SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL);
+        WorkList.push_back(ORNode.Val);
+        return DAG.getSetCC(VT, ORNode, LR, Op1);
+      }
+      // fold (X != -1) | (Y != -1) -> (X&Y != -1)
+      // fold (X >  -1) | (Y >  -1) -> (X&Y >  -1)
+      if (cast<ConstantSDNode>(LR)->isAllOnesValue() && 
+          (Op1 == ISD::SETNE || Op1 == ISD::SETGT)) {
+        SDOperand ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL);
+        WorkList.push_back(ANDNode.Val);
+        return DAG.getSetCC(VT, ANDNode, LR, Op1);
+      }
+    }
+    // canonicalize equivalent to ll == rl
+    if (LL == RR && LR == RL) {
+      Op1 = ISD::getSetCCSwappedOperands(Op1);
+      std::swap(RL, RR);
+    }
+    if (LL == RL && LR == RR) {
+      bool isInteger = MVT::isInteger(LL.getValueType());
+      ISD::CondCode Result = ISD::getSetCCOrOperation(Op0, Op1, isInteger);
+      if (Result != ISD::SETCC_INVALID)
+        return DAG.getSetCC(N0.getValueType(), LL, LR, Result);
+    }
+  }
+  // fold (or (zext x), (zext y)) -> (zext (or x, y))
+  if (N0.getOpcode() == ISD::ZERO_EXTEND && 
+      N1.getOpcode() == ISD::ZERO_EXTEND &&
+      N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
+    SDOperand ORNode = DAG.getNode(ISD::OR, N0.getOperand(0).getValueType(),
+                                   N0.getOperand(0), N1.getOperand(0));
+    WorkList.push_back(ORNode.Val);
+    return DAG.getNode(ISD::ZERO_EXTEND, VT, ORNode);
+  }
   return SDOperand();
 }
 
@@ -733,6 +827,15 @@
   // fold (xor x, x) -> 0
   if (N0 == N1)
     return DAG.getConstant(0, VT);
+  // fold (xor (zext x), (zext y)) -> (zext (xor x, y))
+  if (N0.getOpcode() == ISD::ZERO_EXTEND && 
+      N1.getOpcode() == ISD::ZERO_EXTEND &&
+      N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
+    SDOperand XORNode = DAG.getNode(ISD::XOR, N0.getOperand(0).getValueType(),
+                                   N0.getOperand(0), N1.getOperand(0));
+    WorkList.push_back(XORNode.Val);
+    return DAG.getNode(ISD::ZERO_EXTEND, VT, XORNode);
+  }
   return SDOperand();
 }
 


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.189 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.190
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.189	Thu Sep  8 15:18:10 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Fri Sep  9 14:49:52 2005
@@ -1310,10 +1310,10 @@
     }
   }
 
+  if (!CombinerEnabled) {
   if (N2C) {
     uint64_t C2 = N2C->getValue();
 
-    if (!CombinerEnabled) {
     switch (Opcode) {
     case ISD::ADD:
       if (!C2) return N1;         // add X, 0 -> X
@@ -1486,7 +1486,7 @@
       if (ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N1.Val->getOperand(1)))
         return getNode(Opcode, VT, N1.Val->getOperand(0),
                        getNode(Opcode, VT, N2, N1.Val->getOperand(1)));
-    }
+  }
   }
 
   ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1.Val);
@@ -1533,6 +1533,7 @@
 
   case ISD::AND:
   case ISD::OR:
+    if (!CombinerEnabled) {
     if (N1.Val->getOpcode() == ISD::SETCC && N2.Val->getOpcode() == ISD::SETCC){
       SDNode *LHS = N1.Val, *RHS = N2.Val;
       SDOperand LL = LHS->getOperand(0), RL = RHS->getOperand(0);
@@ -1595,6 +1596,7 @@
       return getNode(ISD::ZERO_EXTEND, VT,
                      getNode(Opcode, N1.getOperand(0).getValueType(),
                              N1.getOperand(0), N2.getOperand(0)));
+    }
     break;
   case ISD::XOR:
     if (!CombinerEnabled) {






More information about the llvm-commits mailing list