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

Chris Lattner lattner at cs.uiuc.edu
Thu Apr 7 11:15:15 PDT 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

SelectionDAG.cpp updated: 1.60 -> 1.61
---
Log message:

This patch does two things.  First, it canonicalizes 'X >= C' -> 'X > C-1'
(likewise for <= >=u >=u).

Second, it implements a special case hack to turn 'X gtu SINTMAX' -> 'X lt 0'

On powerpc, for example, this changes this:

        lis r2, 32767
        ori r2, r2, 65535
        cmplw cr0, r3, r2
        bgt .LBB_test_2

into:

        cmpwi cr0, r3, 0
        blt .LBB_test_2



---
Diffs of the changes:  (+49 -7)

 SelectionDAG.cpp |   56 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 49 insertions(+), 7 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.60 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.61
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.60	Wed Apr  6 19:30:13 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Thu Apr  7 13:14:58 2005
@@ -375,9 +375,10 @@
   case ISD::SETTRUE2:  return getConstant(1, VT);
   }
 
-  if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val))
-    if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val)) {
-      uint64_t C1 = N1C->getValue(), C2 = N2C->getValue();
+  if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val)) {
+    uint64_t C2 = N2C->getValue();
+    if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val)) {
+      uint64_t C1 = N1C->getValue();
       
       // Sign extend the operands if required
       if (ISD::isSignedIntSetCC(Cond)) {
@@ -398,11 +399,52 @@
       case ISD::SETLE:  return getConstant((int64_t)C1 <= (int64_t)C2, VT);
       case ISD::SETGE:  return getConstant((int64_t)C1 >= (int64_t)C2, VT);
       }
-    } else {
-      // Ensure that the constant occurs on the RHS.
-      Cond = ISD::getSetCCSwappedOperands(Cond);
-      std::swap(N1, N2);
+    } else if (1) {
+      uint64_t MinVal, MaxVal;
+      unsigned OperandBitSize = MVT::getSizeInBits(N2C->getValueType(0));
+      if (ISD::isSignedIntSetCC(Cond)) {
+        MinVal = 1ULL << (OperandBitSize-1);
+        if (OperandBitSize != 1)   // Avoid X >> 64, which is undefined.
+          MaxVal = ~0ULL >> (65-OperandBitSize);
+        else
+          MaxVal = 0;
+      } else {
+        MinVal = 0;
+        MaxVal = ~0ULL >> (64-OperandBitSize);
+      }
+
+      // Canonicalize GE/LE comparisons to use GT/LT comparisons.
+      if (Cond == ISD::SETGE || Cond == ISD::SETUGE) {
+        if (C2 == MinVal) return getConstant(1, VT);   // X >= MIN --> true
+        --C2;                                          // X >= C1 --> X > (C1-1)
+        Cond = (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT;
+        N2 = getConstant(C2, N2.getValueType());
+        N2C = cast<ConstantSDNode>(N2.Val);
+      }
+
+      if (Cond == ISD::SETLE || Cond == ISD::SETULE) {
+        if (C2 == MaxVal) return getConstant(1, VT);   // X <= MAX --> true
+        ++C2;                                          // X <= C1 --> X < (C1+1)
+        Cond = (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT;
+        N2 = getConstant(C2, N2.getValueType());
+        N2C = cast<ConstantSDNode>(N2.Val);
+      }
+
+      // If we have "setcc X, C1", check to see if we can shrink the immediate
+      // by changing cc.
+
+      // SETUGT X, SINTMAX  -> SETLT X, 0
+      if (Cond == ISD::SETUGT && OperandBitSize != 1 &&
+          C2 == (~0ULL >> (65-OperandBitSize)))
+        return getSetCC(ISD::SETLT, VT, N1, getConstant(0, N2.getValueType()));
+
+      // FIXME: Implement the rest of these.
+
     }
+  } else if (isa<ConstantSDNode>(N1.Val)) {
+      // Ensure that the constant occurs on the RHS.
+    return getSetCC(ISD::getSetCCSwappedOperands(Cond), VT, N2, N1);
+  }
 
   if (ConstantFPSDNode *N1C = dyn_cast<ConstantFPSDNode>(N1.Val))
     if (ConstantFPSDNode *N2C = dyn_cast<ConstantFPSDNode>(N2.Val)) {






More information about the llvm-commits mailing list