summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/InstructionSimplify.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2012-02-20 00:42:49 +0000
committerChris Lattner <sabre@nondot.org>2012-02-20 00:42:49 +0000
commit445d8c6b50621fdbc6c7b9a444cc94afed9972b0 (patch)
treecf3700d788727348cec7b57809a8a4db8d4b2889 /llvm/lib/Analysis/InstructionSimplify.cpp
parent2325b24c73652dff8bb58d6b3e4d1ead23a063a3 (diff)
downloadbcm5719-llvm-445d8c6b50621fdbc6c7b9a444cc94afed9972b0.tar.gz
bcm5719-llvm-445d8c6b50621fdbc6c7b9a444cc94afed9972b0.zip
fold comparisons of gep'd alloca points with null to false,
implementing PR12013. We now compile the testcase to: __Z4testv: ## @_Z4testv ## BB#0: ## %_ZN4llvm15SmallVectorImplIiE9push_backERKi.exit pushq %rbx subq $64, %rsp leaq 32(%rsp), %rbx movq %rbx, (%rsp) leaq 64(%rsp), %rax movq %rax, 16(%rsp) movl $1, 32(%rsp) leaq 36(%rsp), %rax movq %rax, 8(%rsp) leaq (%rsp), %rdi callq __Z1gRN4llvm11SmallVectorIiLj8EEE movq (%rsp), %rdi cmpq %rbx, %rdi je LBB0_2 ## BB#1: callq _free LBB0_2: ## %_ZN4llvm11SmallVectorIiLj8EED1Ev.exit addq $64, %rsp popq %rbx ret instead of: __Z4testv: ## @_Z4testv ## BB#0: pushq %rbx subq $64, %rsp xorl %eax, %eax leaq (%rsp), %rbx addq $32, %rbx movq %rbx, (%rsp) movq %rbx, 8(%rsp) leaq 64(%rsp), %rcx movq %rcx, 16(%rsp) je LBB0_2 ## BB#1: movl $1, 32(%rsp) movq %rbx, %rax LBB0_2: ## %_ZN4llvm15SmallVectorImplIiE9push_backERKi.exit addq $4, %rax movq %rax, 8(%rsp) leaq (%rsp), %rdi callq __Z1gRN4llvm11SmallVectorIiLj8EEE movq (%rsp), %rdi cmpq %rbx, %rdi je LBB0_4 ## BB#3: callq _free LBB0_4: ## %_ZN4llvm11SmallVectorIiLj8EED1Ev.exit addq $64, %rsp popq %rbx ret This doesn't shrink clang noticably though. llvm-svn: 150944
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp25
1 files changed, 21 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 88a2c53e806..9b0ce1113ac 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1520,6 +1520,15 @@ static Value *ExtractEquivalentCondition(Value *V, CmpInst::Predicate Pred,
return 0;
}
+/// stripPointerAdjustments - This is like Value::stripPointerCasts, but also
+/// removes inbounds gep operations, regardless of their indices.
+static Value *stripPointerAdjustments(Value *V) {
+ if (GEPOperator *GEP = dyn_cast<GEPOperator>(V))
+ if (GEP->isInBounds())
+ return stripPointerAdjustments(GEP->getOperand(0)->stripPointerCasts());
+ return V;
+}
+
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null.
static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
@@ -1595,10 +1604,18 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
Value *RHSPtr = RHS->stripPointerCasts();
if (LHSPtr == RHSPtr)
return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred));
- if (isa<AllocaInst>(LHSPtr) && (isa<GlobalValue>(RHSPtr) ||
- isa<AllocaInst>(RHSPtr) ||
- isa<ConstantPointerNull>(RHSPtr)))
- return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred));
+
+ // Be more aggressive about stripping pointer adjustments when checking a
+ // comparison of an alloca address to another object. We can rip off all
+ // inbounds GEP operations, even if they are variable.
+ LHSPtr = stripPointerAdjustments(LHSPtr);
+ if (isa<AllocaInst>(LHSPtr)) {
+ RHSPtr = stripPointerAdjustments(RHSPtr);
+ if (LHSPtr != RHSPtr &&
+ (isa<GlobalValue>(RHSPtr) || isa<AllocaInst>(RHSPtr) ||
+ isa<ConstantPointerNull>(RHSPtr)))
+ return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred));
+ }
// If we are comparing with zero then try hard since this is a common case.
if (match(RHS, m_Zero())) {
OpenPOWER on IntegriCloud