Implement PR2206.
authorChris Lattner <sabre@nondot.org>
Sat, 19 Apr 2008 22:17:26 +0000 (22:17 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 19 Apr 2008 22:17:26 +0000 (22:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49967 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/ConstantFold.cpp
test/Assembler/ConstantExprFold.llx

index c15ce96959788fb83520187146d140122b70f631..353a1492f80a01a27ecbcd06ca8efe8167ca1e43 100644 (file)
@@ -548,8 +548,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
       if (CI2->isAllOnesValue())
         return const_cast<Constant*>(C1);                     // X & -1 == X
       
-      // (zext i32 to i64) & 4294967295 -> (zext i32 to i64)
       if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
+        // (zext i32 to i64) & 4294967295 -> (zext i32 to i64)
         if (CE1->getOpcode() == Instruction::ZExt) {
           unsigned DstWidth = CI2->getType()->getBitWidth();
           unsigned SrcWidth =
@@ -559,16 +559,25 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
             return const_cast<Constant*>(C1);
         }
         
+        // If and'ing the address of a global with a constant, fold it.
         if (CE1->getOpcode() == Instruction::PtrToInt && 
             isa<GlobalValue>(CE1->getOperand(0))) {
-          GlobalValue *CPR = cast<GlobalValue>(CE1->getOperand(0));
+          GlobalValue *GV = cast<GlobalValue>(CE1->getOperand(0));
         
-          // Functions are at least 4-byte aligned.  If and'ing the address of a
-          // function with a constant < 4, fold it to zero.
-          if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
-            if (CI->getValue().ult(APInt(CI->getType()->getBitWidth(),4)) && 
-                isa<Function>(CPR))
-              return Constant::getNullValue(CI->getType());
+          // Functions are at least 4-byte aligned.
+          unsigned GVAlign = GV->getAlignment();
+          if (isa<Function>(GV))
+            GVAlign = std::max(GVAlign, 4U);
+          
+          if (GVAlign > 1) {
+            unsigned DstWidth = CI2->getType()->getBitWidth();
+            unsigned SrcWidth = std::min(SrcWidth, Log2_32(GVAlign));
+            APInt BitsNotSet(APInt::getLowBitsSet(DstWidth, SrcWidth));
+
+            // If checking bits we know are clear, return zero.
+            if ((CI2->getValue() & BitsNotSet) == CI2->getValue())
+              return Constant::getNullValue(CI2->getType());
+          }
         }
       }
       break;
index e32cc66e81a94666179268a2418e6671e4e48d5a..89edc24b37ec783ae96aa610d661bd852116cd32 100644 (file)
@@ -24,3 +24,7 @@ global i1 icmp slt (i32* getelementptr (%Ty* @B, i64 0, i32 0),
                    i32* getelementptr (%Ty* @B, i64 0, i32 1))            ; true
 ;global i1 icmp ne (i64* @A, i64* bitcast (%Ty* @B to i64*))                 ; true
 
+; PR2206
+@cons = weak global i32 0, align 8              ; <i32*> [#uses=1]
+global i64 and (i64 ptrtoint (i32* @cons to i64), i64 7)
+