From 009e2650d69fe93bda1864340c5f000e56c52fb8 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 24 Feb 2012 19:01:58 +0000 Subject: [PATCH] fix PR12075, a regression in a recent transform I added. In unreachable code, gep chains can be infinite. Just like "stripPointerCasts", use a set to keep track of visited instructions so we don't recurse infinitely. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151383 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/InstructionSimplify.cpp | 22 ++++++++++++++++++---- test/Transforms/InstSimplify/compare.ll | 10 ++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 9b0ce1113ac..37253f72cf6 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -1522,13 +1522,27 @@ static Value *ExtractEquivalentCondition(Value *V, CmpInst::Predicate Pred, /// stripPointerAdjustments - This is like Value::stripPointerCasts, but also /// removes inbounds gep operations, regardless of their indices. +static Value *stripPointerAdjustmentsImpl(Value *V, + SmallPtrSet &VisitedGEPs) { + GEPOperator *GEP = dyn_cast(V); + if (GEP == 0 || !GEP->isInBounds()) + return V; + + // If we've already seen this GEP, we will end up infinitely looping. This + // can happen in unreachable code. + if (!VisitedGEPs.insert(GEP)) + return V; + + return stripPointerAdjustmentsImpl(GEP->getOperand(0)->stripPointerCasts(), + VisitedGEPs); +} + static Value *stripPointerAdjustments(Value *V) { - if (GEPOperator *GEP = dyn_cast(V)) - if (GEP->isInBounds()) - return stripPointerAdjustments(GEP->getOperand(0)->stripPointerCasts()); - return V; + SmallPtrSet VisitedGEPs; + return stripPointerAdjustmentsImpl(V, VisitedGEPs); } + /// 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, diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll index f22ac46397f..6ee6dfbdbc9 100644 --- a/test/Transforms/InstSimplify/compare.ll +++ b/test/Transforms/InstSimplify/compare.ll @@ -463,3 +463,13 @@ define i1 @alloca_compare(i64 %idx) { ; CHECK: alloca_compare ; CHECK: ret i1 false } + +; PR12075 +define i1 @infinite_gep() { + ret i1 1 + +unreachableblock: + %X = getelementptr i32 *%X, i32 1 + %Y = icmp eq i32* %X, null + ret i1 %Y +} -- 2.34.1