mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-26 01:38:43 +00:00
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
This commit is contained in:
parent
1a2d061ec0
commit
009e2650d6
@ -1522,13 +1522,27 @@ static Value *ExtractEquivalentCondition(Value *V, CmpInst::Predicate Pred,
|
|||||||
|
|
||||||
/// stripPointerAdjustments - This is like Value::stripPointerCasts, but also
|
/// stripPointerAdjustments - This is like Value::stripPointerCasts, but also
|
||||||
/// removes inbounds gep operations, regardless of their indices.
|
/// removes inbounds gep operations, regardless of their indices.
|
||||||
static Value *stripPointerAdjustments(Value *V) {
|
static Value *stripPointerAdjustmentsImpl(Value *V,
|
||||||
if (GEPOperator *GEP = dyn_cast<GEPOperator>(V))
|
SmallPtrSet<GEPOperator*, 8> &VisitedGEPs) {
|
||||||
if (GEP->isInBounds())
|
GEPOperator *GEP = dyn_cast<GEPOperator>(V);
|
||||||
return stripPointerAdjustments(GEP->getOperand(0)->stripPointerCasts());
|
if (GEP == 0 || !GEP->isInBounds())
|
||||||
return V;
|
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) {
|
||||||
|
SmallPtrSet<GEPOperator*, 8> VisitedGEPs;
|
||||||
|
return stripPointerAdjustmentsImpl(V, VisitedGEPs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
|
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||||
|
@ -463,3 +463,13 @@ define i1 @alloca_compare(i64 %idx) {
|
|||||||
; CHECK: alloca_compare
|
; CHECK: alloca_compare
|
||||||
; CHECK: ret i1 false
|
; 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
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user