[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp

Chris Lattner sabre at nondot.org
Sun Sep 17 21:23:03 PDT 2006



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.505 -> 1.506
---
Log message:

Rewrite shift/and/compare sequences to promote better licm of the RHS.
Use isLogicalShift/isArithmeticShift to simplify code.


---
Diffs of the changes:  (+48 -28)

 InstructionCombining.cpp |   76 +++++++++++++++++++++++++++++------------------
 1 files changed, 48 insertions(+), 28 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.505 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.506
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.505	Fri Sep 15 22:14:10 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Sun Sep 17 23:22:48 2006
@@ -3856,7 +3856,7 @@
           // happens a LOT in code produced by the C front-end, for bitfield
           // access.
           ShiftInst *Shift = dyn_cast<ShiftInst>(LHSI->getOperand(0));
-          ConstantInt *AndCST = cast<ConstantInt>(LHSI->getOperand(1));
+          Constant *AndCST = cast<ConstantInt>(LHSI->getOperand(1));
 
           // Check to see if there is a noop-cast between the shift and the and.
           if (!Shift) {
@@ -3866,7 +3866,7 @@
                      CI->getType()->getPrimitiveSizeInBits())
                 Shift = dyn_cast<ShiftInst>(CI->getOperand(0));
           }
-          
+
           ConstantUInt *ShAmt;
           ShAmt = Shift ? dyn_cast<ConstantUInt>(Shift->getOperand(1)) : 0;
           const Type *Ty = Shift ? Shift->getType() : 0;  // Type of the shift.
@@ -3876,8 +3876,7 @@
           // into the mask.  This can only happen with signed shift
           // rights, as they sign-extend.
           if (ShAmt) {
-            bool CanFold = Shift->getOpcode() != Instruction::Shr ||
-                           Ty->isUnsigned();
+            bool CanFold = Shift->isLogicalShift();
             if (!CanFold) {
               // To test for the bad case of the signed shr, see if any
               // of the bits shifted in could be tested after the mask.
@@ -3930,15 +3929,49 @@
               }
             }
           }
+          
+          // Turn ((X >> Y) & C) == 0  into  (X & (C << Y)) == 0.  The later is
+          // preferable because it allows the C<<Y expression to be hoisted out
+          // of a loop if Y is invariant and X is not.
+          if (Shift && Shift->hasOneUse() && CI->isNullValue() &&
+              I.isEquality() && !Shift->isArithmeticShift()) {
+            // Compute C << Y.
+            Value *NS;
+            if (Shift->getOpcode() == Instruction::Shr) {
+              NS = new ShiftInst(Instruction::Shl, AndCST, Shift->getOperand(1),
+                                 "tmp");
+            } else {
+              // Make sure we insert a logical shift.
+              if (AndCST->getType()->isSigned())
+                AndCST = ConstantExpr::getCast(AndCST,
+                                      AndCST->getType()->getUnsignedVersion());
+              NS = new ShiftInst(Instruction::Shr, AndCST, Shift->getOperand(1),
+                                 "tmp");
+            }
+            InsertNewInstBefore(cast<Instruction>(NS), I);
+
+            // If C's sign doesn't agree with the and, insert a cast now.
+            if (NS->getType() != LHSI->getType())
+              NS = InsertCastBefore(NS, LHSI->getType(), I);
+
+            Value *ShiftOp = Shift->getOperand(0);
+            if (ShiftOp->getType() != LHSI->getType())
+              ShiftOp = InsertCastBefore(ShiftOp, LHSI->getType(), I);
+              
+            // Compute X & (C << Y).
+            Instruction *NewAnd =
+              BinaryOperator::createAnd(ShiftOp, NS, LHSI->getName());
+            InsertNewInstBefore(NewAnd, I);
+            
+            I.setOperand(0, NewAnd);
+            return &I;
+          }
         }
         break;
 
       case Instruction::Shl:         // (setcc (shl X, ShAmt), CI)
         if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) {
-          switch (I.getOpcode()) {
-          default: break;
-          case Instruction::SetEQ:
-          case Instruction::SetNE: {
+          if (I.isEquality()) {
             unsigned TypeBits = CI->getType()->getPrimitiveSizeInBits();
 
             // Check that the shift amount is in range.  If not, don't perform
@@ -3979,17 +4012,12 @@
                                      ConstantExpr::getUShr(CI, ShAmt));
             }
           }
-          }
         }
         break;
 
       case Instruction::Shr:         // (setcc (shr X, ShAmt), CI)
         if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) {
-          switch (I.getOpcode()) {
-          default: break;
-          case Instruction::SetEQ:
-          case Instruction::SetNE: {
-
+          if (I.isEquality()) {
             // Check that the shift amount is in range.  If not, don't perform
             // undefined shifts.  When the shift is visited it will be
             // simplified.
@@ -4030,8 +4058,6 @@
               return new SetCondInst(I.getOpcode(), And,
                                      ConstantExpr::getShl(CI, ShAmt));
             }
-            break;
-          }
           }
         }
         break;
@@ -4130,8 +4156,7 @@
       }
 
     // Simplify seteq and setne instructions...
-    if (I.getOpcode() == Instruction::SetEQ ||
-        I.getOpcode() == Instruction::SetNE) {
+    if (I.isEquality()) {
       bool isSetNE = I.getOpcode() == Instruction::SetNE;
 
       // If the first operand is (and|or|xor) with a constant, and the second
@@ -4361,9 +4386,7 @@
   if (CastInst *CI = dyn_cast<CastInst>(Op0)) {
     Value *CastOp0 = CI->getOperand(0);
     if (CastOp0->getType()->isLosslesslyConvertibleTo(CI->getType()) &&
-        (isa<Constant>(Op1) || isa<CastInst>(Op1)) &&
-        (I.getOpcode() == Instruction::SetEQ ||
-         I.getOpcode() == Instruction::SetNE)) {
+        (isa<Constant>(Op1) || isa<CastInst>(Op1)) && I.isEquality()) {
       // We keep moving the cast from the left operand over to the right
       // operand, where it can often be eliminated completely.
       Op0 = CastOp0;
@@ -4398,8 +4421,7 @@
         return R;
   }
   
-  if (I.getOpcode() == Instruction::SetNE ||
-      I.getOpcode() == Instruction::SetEQ) {
+  if (I.isEquality()) {
     Value *A, *B;
     if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&
         (A == Op1 || B == Op1)) {
@@ -4552,7 +4574,7 @@
         return R;
 
   // See if we can turn a signed shr into an unsigned shr.
-  if (!isLeftShift && I.getType()->isSigned()) {
+  if (I.isArithmeticShift()) {
     if (MaskedValueIsZero(Op0,
                           1ULL << (I.getType()->getPrimitiveSizeInBits()-1))) {
       Value *V = InsertCastBefore(Op0, I.getType()->getUnsignedVersion(), I);
@@ -5617,10 +5639,8 @@
       // non-constant value, eliminate this whole mess.  This corresponds to
       // cases like this: ((X & 27) ? 27 : 0)
       if (TrueValC->isNullValue() || FalseValC->isNullValue())
-        if (Instruction *IC = dyn_cast<Instruction>(SI.getCondition()))
-          if ((IC->getOpcode() == Instruction::SetEQ ||
-               IC->getOpcode() == Instruction::SetNE) &&
-              isa<ConstantInt>(IC->getOperand(1)) &&
+        if (SetCondInst *IC = dyn_cast<SetCondInst>(SI.getCondition()))
+          if (IC->isEquality() && isa<ConstantInt>(IC->getOperand(1)) &&
               cast<Constant>(IC->getOperand(1))->isNullValue())
             if (Instruction *ICA = dyn_cast<Instruction>(IC->getOperand(0)))
               if (ICA->getOpcode() == Instruction::And &&






More information about the llvm-commits mailing list