diff options
author | Chris Lattner <sabre@nondot.org> | 2008-04-19 22:17:26 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-04-19 22:17:26 +0000 |
commit | 510fabb24c0a6db38a87d33b65ff90e5b1377015 (patch) | |
tree | 759c384cfde897c617a82b0d6ef9c061e37818db /lib/VMCore/ConstantFold.cpp | |
parent | 69e4c5b6ff7532bfaf94bd102377be02af891761 (diff) | |
download | external_llvm-510fabb24c0a6db38a87d33b65ff90e5b1377015.tar.gz external_llvm-510fabb24c0a6db38a87d33b65ff90e5b1377015.tar.bz2 external_llvm-510fabb24c0a6db38a87d33b65ff90e5b1377015.zip |
Implement PR2206.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49967 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/ConstantFold.cpp')
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index c15ce96959..353a1492f8 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -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; |