Implement X / C1 / C2 folding
authorChris Lattner <sabre@nondot.org>
Tue, 28 Sep 2004 18:22:15 +0000 (18:22 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 28 Sep 2004 18:22:15 +0000 (18:22 +0000)
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

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

lib/Transforms/Scalar/InstructionCombining.cpp

index 6441b34faa3cc38c1fb46d6a486cf7e80a60161b..7fce33bbf911ac6fb2b43e179941f4882b4abbf1 100644 (file)
@@ -818,6 +818,15 @@ Instruction *InstCombiner::visitDiv(BinaryOperator &I) {
     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 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &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 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 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
             }
               
             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 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
         }
         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