From 8cde1e71f02eccc165bb2d8d819b7ff48ddb9261 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 19 Apr 2008 22:17:26 +0000 Subject: [PATCH] Implement PR2206. llvm-svn: 49967 --- lib/VMCore/ConstantFold.cpp | 25 +++++++++++++++++-------- test/Assembler/ConstantExprFold.llx | 4 ++++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index c15ce969597..353a1492f80 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(C1); // X & -1 == X - // (zext i32 to i64) & 4294967295 -> (zext i32 to i64) if (const ConstantExpr *CE1 = dyn_cast(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(C1); } + // If and'ing the address of a global with a constant, fold it. if (CE1->getOpcode() == Instruction::PtrToInt && isa(CE1->getOperand(0))) { - GlobalValue *CPR = cast(CE1->getOperand(0)); + GlobalValue *GV = cast(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(C2)) - if (CI->getValue().ult(APInt(CI->getType()->getBitWidth(),4)) && - isa(CPR)) - return Constant::getNullValue(CI->getType()); + // Functions are at least 4-byte aligned. + unsigned GVAlign = GV->getAlignment(); + if (isa(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; diff --git a/test/Assembler/ConstantExprFold.llx b/test/Assembler/ConstantExprFold.llx index e32cc66e81a..89edc24b37e 100644 --- a/test/Assembler/ConstantExprFold.llx +++ b/test/Assembler/ConstantExprFold.llx @@ -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 ; [#uses=1] +global i64 and (i64 ptrtoint (i32* @cons to i64), i64 7) +