fold constantexprs more aggressively, fixing PR1265
authorChris Lattner <sabre@nondot.org>
Sun, 25 Mar 2007 05:47:04 +0000 (05:47 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 25 Mar 2007 05:47:04 +0000 (05:47 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35336 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/ConstantFold.cpp

index d7e51956e4d274031f77253b75037d5c03745f69..46263060e5767a1811d6162fa93d6f71dcd6fa46 100644 (file)
@@ -519,10 +519,20 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
             return Constant::getNullValue(CI->getType());         // X % 1 == 0
         break;
       case Instruction::And:
-        if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
+        if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2)) {
+          if (CI->isZero()) return const_cast<Constant*>(C2);     // X & 0 == 0
           if (CI->isAllOnesValue())
             return const_cast<Constant*>(C1);                     // X & -1 == X
-        if (C2->isNullValue()) return const_cast<Constant*>(C2);  // X & 0 == 0
+          
+          // (zext i32 to i64) & 4294967295 -> (zext i32 to i64)
+          if (CE1->getOpcode() == Instruction::ZExt) {
+            APInt PossiblySetBits
+              = cast<IntegerType>(CE1->getOperand(0)->getType())->getMask();
+            PossiblySetBits.zext(C1->getType()->getPrimitiveSizeInBits());
+            if ((PossiblySetBits & CI->getValue()) == PossiblySetBits)
+              return const_cast<Constant*>(C1);
+          }
+        }
         if (CE1->isCast() && isa<GlobalValue>(CE1->getOperand(0))) {
           GlobalValue *CPR = cast<GlobalValue>(CE1->getOperand(0));
 
@@ -543,6 +553,11 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
       case Instruction::Xor:
         if (C2->isNullValue()) return const_cast<Constant*>(C1);  // X ^ 0 == X
         break;
+      case Instruction::AShr:
+        if (CE1->getOpcode() == Instruction::ZExt)  // Top bits known zero.
+          return ConstantExpr::getLShr(const_cast<Constant*>(C1),
+                                       const_cast<Constant*>(C2));
+        break;
       }
     }
   } else if (isa<ConstantExpr>(C2)) {