From: Chris Lattner Date: Sun, 13 Feb 2011 03:14:49 +0000 (+0000) Subject: teach SCEV that the scale and addition of an inbounds gep don't NSW. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=8ebaf909580ada88d9952327323ded1e328d0708;p=oota-llvm.git 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125449 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index aab95ae1f64..62244ccb3a0 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -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 diff --git a/test/Analysis/ScalarEvolution/nsw.ll b/test/Analysis/ScalarEvolution/nsw.ll index 010cf604a87..9d8e2b62a9d 100644 --- a/test/Analysis/ScalarEvolution/nsw.ll +++ b/test/Analysis/ScalarEvolution/nsw.ll @@ -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}<%for.body.i.i> + %tmp = add nsw i64 %indvar.i.i, 1 +; CHECK: %tmp = +; CHECK: {1,+,1}<%for.body.i.i> + %ptrincdec.i.i = getelementptr inbounds i32* %begin, i64 %tmp +; CHECK: %ptrincdec.i.i = +; CHECK: {(4 + %begin),+,4}<%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}<%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 +} \ No newline at end of file diff --git a/test/Analysis/ScalarEvolution/scev-aa.ll b/test/Analysis/ScalarEvolution/scev-aa.ll index 866664a3d66..dd5a66ccb44 100644 --- a/test/Analysis/ScalarEvolution/scev-aa.ll +++ b/test/Analysis/ScalarEvolution/scev-aa.ll @@ -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