Add cannonicalization of shl X, 1 -> add X, X
[oota-llvm.git] / lib / Transforms / Scalar / InstructionCombining.cpp
index 128d76652612f698888316189bdbee593f126943..9c1076e448148f2d3d072bfbb0857ea5c427dd85 100644 (file)
@@ -217,10 +217,10 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
 
   // Simplify mul instructions with a constant RHS...
   if (Constant *Op2 = dyn_cast<Constant>(I.getOperand(1))) {
-    if (I.getType()->isIntegral() && cast<ConstantInt>(Op2)->equalsInt(1))
+    if (I.getType()->isInteger() && cast<ConstantInt>(Op2)->equalsInt(1))
       return ReplaceInstUsesWith(I, Op1);  // Eliminate 'mul int %X, 1'
 
-    if (I.getType()->isIntegral() && cast<ConstantInt>(Op2)->equalsInt(2))
+    if (I.getType()->isInteger() && cast<ConstantInt>(Op2)->equalsInt(2))
       // Convert 'mul int %X, 2' to 'add int %X, %X'
       return BinaryOperator::create(Instruction::Add, Op1, Op1, I.getName());
 
@@ -490,22 +490,23 @@ Instruction *InstCombiner::visitShiftInst(Instruction &I) {
   // a signed value.
   //
   if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1)) {
-    unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8;
-    if (CUI->getValue() >= TypeBits &&
-        !(Op0->getType()->isSigned() && I.getOpcode() == Instruction::Shr))
-      return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
+    if (I.getOpcode() == Instruction::Shr) {
+      unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8;
+      if (CUI->getValue() >= TypeBits && !(Op0->getType()->isSigned()))
+        return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
+    }
+
+    // Check to see if we are shifting left by 1.  If so, turn it into an add
+    // instruction.
+    if (I.getOpcode() == Instruction::Shl && CUI->equalsInt(1))
+      // Convert 'shl int %X, 2' to 'add int %X, %X'
+      return BinaryOperator::create(Instruction::Add, Op0, Op0, I.getName());
+
   }
   return 0;
 }
 
 
-// isCIntegral - For the purposes of casting, we allow conversion of sizes and
-// stuff as long as the value type acts basically integral like.
-//
-static bool isCIntegral(const Type *Ty) {
-  return Ty->isIntegral() || Ty == Type::BoolTy;
-}
-
 // isEliminableCastOfCast - Return true if it is valid to eliminate the CI
 // instruction.
 //
@@ -524,7 +525,7 @@ static inline bool isEliminableCastOfCast(const CastInst &CI,
 
   // Allow free casting and conversion of sizes as long as the sign doesn't
   // change...
-  if (isCIntegral(SrcTy) && isCIntegral(MidTy) && isCIntegral(DstTy)) {
+  if (SrcTy->isIntegral() && MidTy->isIntegral() && DstTy->isIntegral()) {
     unsigned SrcSize = SrcTy->getPrimitiveSize();
     unsigned MidSize = MidTy->getPrimitiveSize();
     unsigned DstSize = DstTy->getPrimitiveSize();
@@ -597,7 +598,7 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
     // to convert this into a logical 'and' instruction.
     //
     if (CSrc->getOperand(0)->getType() == CI.getType() &&
-        CI.getType()->isIntegral() && CSrc->getType()->isIntegral() &&
+        CI.getType()->isInteger() && CSrc->getType()->isInteger() &&
         CI.getType()->isUnsigned() && CSrc->getType()->isUnsigned() &&
         CSrc->getType()->getPrimitiveSize() < CI.getType()->getPrimitiveSize()){
       assert(CSrc->getType() != Type::ULongTy &&