Per discussion with Dan G, inbounds geps *certainly* can have
authorChris Lattner <sabre@nondot.org>
Fri, 11 Feb 2011 21:43:33 +0000 (21:43 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 11 Feb 2011 21:43:33 +0000 (21:43 +0000)
unsigned overflow (e.g. "gep P, -1"), and while they can have
signed wrap in theoretical situations, modelling an AddRec as
not having signed wrap is going enough for any case we can
think of today.  In the future if this isn't enough, we can
revisit this.  Modeling them as having NUW isn't causing any
known problems either FWIW.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125410 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ScalarEvolution.cpp
test/Analysis/ScalarEvolution/nsw.ll

index c2f3ac071de2c7e3a3c64000ba87ac19ae5c0536..aab95ae1f6406bf3dbcf3eaf1723c5f546891312 100644 (file)
@@ -2785,10 +2785,21 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
                   HasNSW = true;
               } else if (const GEPOperator *GEP = 
                             dyn_cast<GEPOperator>(BEValueV)) {
-                // If the increment is a GEP, then we know it won't perform an
-                // unsigned overflow, because the address space cannot be
+                // If the increment is a GEP, then we know it won't perform a
+                // signed overflow, because the address space cannot be
                 // wrapped around.
-                HasNUW |= GEP->isInBounds();
+                //
+                // NOTE: This isn't strictly true, because you could have an
+                // object straddling the 2G address boundary in a 32-bit address
+                // space (for example).  We really want to model this as a "has
+                // no signed/unsigned wrap" where the base pointer is treated as
+                // unsigned and the increment is known to not have signed
+                // wrapping.
+                //
+                // This is a highly theoretical concern though, and this is good
+                // enough for all cases we know of at this point. :)
+                //                
+                HasNSW |= GEP->isInBounds();
               }
 
               const SCEV *StartVal = getSCEV(StartValueV);
index 530ed39ac1c099286aa0339859b8ef0f89f86a90..010cf604a871a6ebc65bd01847f9ed9bd4d0127f 100644 (file)
@@ -62,11 +62,11 @@ for.body.lr.ph.i.i:                               ; preds = %entry
 for.body.i.i:                                     ; preds = %for.body.i.i, %for.body.lr.ph.i.i
   %__first.addr.02.i.i = phi i32* [ %begin, %for.body.lr.ph.i.i ], [ %ptrincdec.i.i, %for.body.i.i ]
 ; CHECK: %__first.addr.02.i.i
-; CHECK-NEXT: -->  {%begin,+,4}<nuw><%for.body.i.i>    
+; CHECK-NEXT: -->  {%begin,+,4}<nsw><%for.body.i.i>    
   store i32 0, i32* %__first.addr.02.i.i, align 4
   %ptrincdec.i.i = getelementptr inbounds i32* %__first.addr.02.i.i, i64 1
 ; CHECK: %ptrincdec.i.i
-; CHECK-NEXT: -->  {(4 + %begin),+,4}<nuw><%for.body.i.i>
+; CHECK-NEXT: -->  {(4 + %begin),+,4}<nsw><%for.body.i.i>
   %cmp.i.i = icmp eq i32* %ptrincdec.i.i, %end
   br i1 %cmp.i.i, label %for.cond.for.end_crit_edge.i.i, label %for.body.i.i