diff options
author | Chris Lattner <sabre@nondot.org> | 2012-02-20 00:42:49 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2012-02-20 00:42:49 +0000 |
commit | b053fc1c92b6b81c47d5e2c092b0f3ea04fd5b87 (patch) | |
tree | 185c5b92d6e2538f8c30edc1202c4d253529713f /lib | |
parent | 637f949a7fc97aa42e7360e9ed9462316b772d88 (diff) | |
download | external_llvm-b053fc1c92b6b81c47d5e2c092b0f3ea04fd5b87.zip external_llvm-b053fc1c92b6b81c47d5e2c092b0f3ea04fd5b87.tar.gz external_llvm-b053fc1c92b6b81c47d5e2c092b0f3ea04fd5b87.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150944 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/InstructionSimplify.cpp | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 88a2c53..9b0ce11 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/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())) { |