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
This commit is contained in:
Chris Lattner 2012-02-20 00:42:49 +00:00
parent 637f949a7f
commit b053fc1c92
2 changed files with 33 additions and 5 deletions

View File

@ -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())) {

View File

@ -446,9 +446,20 @@ define <2 x i1> @vectorselect1(<2 x i1> %cond) {
; CHECK: ret <2 x i1> %cond
}
define <2 x i1> @vectorselectcrash(i32 %arg1) { ; PR11948
; PR11948
define <2 x i1> @vectorselectcrash(i32 %arg1) {
%tobool40 = icmp ne i32 %arg1, 0
%cond43 = select i1 %tobool40, <2 x i16> <i16 -5, i16 66>, <2 x i16> <i16 46, i16 1>
%cmp45 = icmp ugt <2 x i16> %cond43, <i16 73, i16 21>
ret <2 x i1> %cmp45
}
; PR12013
define i1 @alloca_compare(i64 %idx) {
%sv = alloca { i32, i32, [124 x i32] }
%1 = getelementptr inbounds { i32, i32, [124 x i32] }* %sv, i32 0, i32 2, i64 %idx
%2 = icmp eq i32* %1, null
ret i1 %2
; CHECK: alloca_compare
; CHECK: ret i1 false
}