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

Chris Lattner lattner at cs.uiuc.edu
Tue Sep 28 11:22:25 PDT 2004



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.252 -> 1.253
---
Log message:

Implement X / C1 / C2 folding
Implement (setcc (shl X, C1), C2) folding.

The second one occurs several dozen times in spec.  The first was added
just in case.  :)

These are tested by shift.ll:test2[12], and div.ll:test5



---
Diffs of the changes:  (+54 -8)

Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.252 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.253
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.252	Tue Sep 28 12:54:07 2004
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Tue Sep 28 13:22:15 2004
@@ -818,6 +818,15 @@
     if (RHS->isAllOnesValue())
       return BinaryOperator::createNeg(I.getOperand(0));
 
+    if (Instruction *LHS = dyn_cast<Instruction>(I.getOperand(0)))
+      if (LHS->getOpcode() == Instruction::Div)
+        if (ConstantInt *LHSRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) {
+          std::cerr << "DIV: " << *LHS << "   : " << I;
+          // (X / C1) / C2  -> X / (C1*C2)
+          return BinaryOperator::createDiv(LHS->getOperand(0),
+                                           ConstantExpr::getMul(RHS, LHSRHS));
+        }
+
     // Check to see if this is an unsigned division with an exact power of 2,
     // if so, convert to a right shift.
     if (ConstantUInt *C = dyn_cast<ConstantUInt>(RHS))
@@ -1553,10 +1562,51 @@
         }
         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 we are comparing against bits always shifted out, the
+            // comparison cannot succeed.
+            Constant *Comp = 
+              ConstantExpr::getShl(ConstantExpr::getShr(CI, ShAmt), ShAmt);
+            if (Comp != CI) {// Comparing against a bit that we know is zero.
+              bool IsSetNE = I.getOpcode() == Instruction::SetNE;
+              Constant *Cst = ConstantBool::get(IsSetNE);
+              return ReplaceInstUsesWith(I, Cst);
+            }
+
+            if (LHSI->hasOneUse()) {
+              // Otherwise strength reduce the shift into an and.
+              unsigned ShAmtVal = ShAmt->getValue();
+              unsigned TypeBits = CI->getType()->getPrimitiveSize()*8;
+              uint64_t Val = (1ULL << (TypeBits-ShAmtVal))-1;
+
+              Constant *Mask;
+              if (CI->getType()->isUnsigned()) {
+                Mask = ConstantUInt::get(CI->getType(), Val);
+              } else if (ShAmtVal != 0) {
+                Mask = ConstantSInt::get(CI->getType(), Val);
+              } else {
+                Mask = ConstantInt::getAllOnesValue(CI->getType());
+              }
+              
+              Instruction *AndI =
+                BinaryOperator::createAnd(LHSI->getOperand(0),
+                                          Mask, LHSI->getName()+".mask");
+              Value *And = InsertNewInstBefore(AndI, I);
+              return new SetCondInst(I.getOpcode(), And,
+                                     ConstantExpr::getUShr(CI, ShAmt));
+            }
+          }
+          }
+        }
+        break;
+
       case Instruction::Shr:         // (setcc (shr X, ShAmt), CI)
         if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) {
-          unsigned ShAmtVal = ShAmt->getValue();
-          
           switch (I.getOpcode()) {
           default: break;
           case Instruction::SetEQ:
@@ -1573,6 +1623,8 @@
             }
               
             if (LHSI->hasOneUse() || CI->isNullValue()) {
+              unsigned ShAmtVal = ShAmt->getValue();
+
               // Otherwise strength reduce the shift into an and.
               uint64_t Val = ~0ULL;          // All ones.
               Val <<= ShAmtVal;              // Shift over to the right spot.
@@ -1599,12 +1651,6 @@
         }
         break;
 
-      case Instruction::Div:
-        if (0 && isa<ConstantInt>(LHSI->getOperand(1))) {
-          std::cerr << "COULD FOLD: " << *LHSI;
-          std::cerr << "COULD FOLD: " << I << "\n";
-        }
-        break;
       case Instruction::Select:
         // If either operand of the select is a constant, we can fold the
         // comparison into the select arms, which will cause one to be






More information about the llvm-commits mailing list