aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore/ConstantFold.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-04-19 22:17:26 +0000
committerChris Lattner <sabre@nondot.org>2008-04-19 22:17:26 +0000
commitd881ad2c570dcb5965eb00b66462e1075ec82440 (patch)
tree759c384cfde897c617a82b0d6ef9c061e37818db /lib/VMCore/ConstantFold.cpp
parent1c14c297460e0a6480bab989c0ade346288bbfd2 (diff)
downloadexternal_llvm-d881ad2c570dcb5965eb00b66462e1075ec82440.zip
external_llvm-d881ad2c570dcb5965eb00b66462e1075ec82440.tar.gz
external_llvm-d881ad2c570dcb5965eb00b66462e1075ec82440.tar.bz2
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.cpp25
1 files changed, 17 insertions, 8 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index c15ce96..353a149 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;