1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

teach SCEV that the scale and addition of an inbounds gep don't NSW.

This fixes a FIXME in scev-aa.ll (allowing a new no-alias result) and
generally makes things more precise.

llvm-svn: 125449
This commit is contained in:
Chris Lattner 2011-02-13 03:14:49 +00:00
parent 0e68b2ed88
commit 2596ac19b9
3 changed files with 36 additions and 6 deletions

View File

@ -2870,6 +2870,7 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) {
// Add expression, because the Instruction may be guarded by control flow
// and the no-overflow bits may not be valid for the expression in any
// context.
bool isInBounds = GEP->isInBounds();
const Type *IntPtrTy = getEffectiveSCEVType(GEP->getType());
Value *Base = GEP->getOperand(0);
@ -2898,7 +2899,8 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) {
IndexS = getTruncateOrSignExtend(IndexS, IntPtrTy);
// Multiply the index by the element size to compute the element offset.
const SCEV *LocalOffset = getMulExpr(IndexS, ElementSize);
const SCEV *LocalOffset = getMulExpr(IndexS, ElementSize, /*NUW*/ false,
/*NSW*/ isInBounds);
// Add the element offset to the running total offset.
TotalOffset = getAddExpr(TotalOffset, LocalOffset);
@ -2909,7 +2911,8 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) {
const SCEV *BaseS = getSCEV(Base);
// Add the total offset from all the GEP indices to the base.
return getAddExpr(BaseS, TotalOffset);
return getAddExpr(BaseS, TotalOffset, /*NUW*/ false,
/*NSW*/ isInBounds);
}
/// GetMinTrailingZeros - Determine the minimum number of zero bits that S is

View File

@ -76,3 +76,31 @@ for.cond.for.end_crit_edge.i.i: ; preds = %for.body.i.i
_ZSt4fillIPiiEvT_S1_RKT0_.exit: ; preds = %entry, %for.cond.for.end_crit_edge.i.i
ret void
}
; Various checks for inbounds geps.
define void @test3(i32* %begin, i32* %end) nounwind ssp {
entry:
%cmp7.i.i = icmp eq i32* %begin, %end
br i1 %cmp7.i.i, label %_ZSt4fillIPiiEvT_S1_RKT0_.exit, label %for.body.i.i
for.body.i.i: ; preds = %entry, %for.body.i.i
%indvar.i.i = phi i64 [ %tmp, %for.body.i.i ], [ 0, %entry ]
; CHECK: %indvar.i.i
; CHECK: {0,+,1}<nuw><nsw><%for.body.i.i>
%tmp = add nsw i64 %indvar.i.i, 1
; CHECK: %tmp =
; CHECK: {1,+,1}<nuw><nsw><%for.body.i.i>
%ptrincdec.i.i = getelementptr inbounds i32* %begin, i64 %tmp
; CHECK: %ptrincdec.i.i =
; CHECK: {(4 + %begin),+,4}<nsw><%for.body.i.i>
%__first.addr.08.i.i = getelementptr inbounds i32* %begin, i64 %indvar.i.i
; CHECK: %__first.addr.08.i.i
; CHECK: {%begin,+,4}<nsw><%for.body.i.i>
store i32 0, i32* %__first.addr.08.i.i, align 4
%cmp.i.i = icmp eq i32* %ptrincdec.i.i, %end
br i1 %cmp.i.i, label %_ZSt4fillIPiiEvT_S1_RKT0_.exit, label %for.body.i.i
; CHECK: Loop %for.body.i.i: Unpredictable backedge-taken count.
; CHECK: Loop %for.body.i.i: Unpredictable max backedge-taken count.
_ZSt4fillIPiiEvT_S1_RKT0_.exit: ; preds = %for.body.i.i, %entry
ret void
}

View File

@ -190,9 +190,8 @@ define void @bar() {
ret void
}
; TODO: This is theoretically provable to be NoAlias.
; CHECK: Function: nonnegative: 2 pointers, 0 call sites
; CHECK: MayAlias: i64* %arrayidx, i64* %p
; CHECK: NoAlias: i64* %arrayidx, i64* %p
define void @nonnegative(i64* %p) nounwind {
entry:
@ -211,6 +210,6 @@ for.end: ; preds = %for.body, %entry
ret void
}
; CHECK: 13 no alias responses
; CHECK: 27 may alias responses
; CHECK: 14 no alias responses
; CHECK: 26 may alias responses
; CHECK: 18 must alias responses