From b053fc1c92b6b81c47d5e2c092b0f3ea04fd5b87 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 20 Feb 2012 00:42:49 +0000 Subject: [PATCH] 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 --- lib/Analysis/InstructionSimplify.cpp | 25 +++++++++++++++++++++---- test/Transforms/InstSimplify/compare.ll | 13 ++++++++++++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 88a2c53e806..9b0ce1113ac 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(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(LHSPtr) && (isa(RHSPtr) || - isa(RHSPtr) || - isa(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(LHSPtr)) { + RHSPtr = stripPointerAdjustments(RHSPtr); + if (LHSPtr != RHSPtr && + (isa(RHSPtr) || isa(RHSPtr) || + isa(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())) { diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll index 92b8fc7e3a9..f22ac46397f 100644 --- a/test/Transforms/InstSimplify/compare.ll +++ b/test/Transforms/InstSimplify/compare.ll @@ -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> , <2 x i16> %cmp45 = icmp ugt <2 x i16> %cond43, 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 +} -- 2.34.1