[llvm] 406e9c9 - [SCEV] Use object size for allocas as well

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 23 03:40:41 PDT 2023


Author: Nikita Popov
Date: 2023-06-23T12:38:12+02:00
New Revision: 406e9c93726ed929ca09ffed2fd3a60cfd633f4b

URL: https://github.com/llvm/llvm-project/commit/406e9c93726ed929ca09ffed2fd3a60cfd633f4b
DIFF: https://github.com/llvm/llvm-project/commit/406e9c93726ed929ca09ffed2fd3a60cfd633f4b.diff

LOG: [SCEV] Use object size for allocas as well

The object size and alignment based restriction on the possible
allocation range also applies to allocas, not just globals, so
handle them as well.

We shouldn't really need any type restriction here at all, but
for now stay conservative.

Added: 
    

Modified: 
    llvm/lib/Analysis/ScalarEvolution.cpp
    llvm/test/Analysis/ScalarEvolution/nsw.ll
    llvm/test/Analysis/ScalarEvolution/sdiv.ll
    llvm/test/Analysis/ScalarEvolution/srem.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 827e4f676fc1d..2d1caf5ea1cf5 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6815,14 +6815,14 @@ const ConstantRange &ScalarEvolution::getRangeRef(
           RangeType);
 
     if (U->getType()->isPointerTy() && SignHint == HINT_RANGE_UNSIGNED) {
-      // Strengthen the range if the underlying IR value is a global using the
-      // size of the global.
+      // Strengthen the range if the underlying IR value is a global/alloca
+      // using the size of the object.
       ObjectSizeOpts Opts;
       Opts.RoundToAlign = false;
       Opts.NullIsUnknownSize = true;
       uint64_t ObjSize;
-      auto *GV = dyn_cast<GlobalVariable>(V);
-      if (GV && getObjectSize(V, ObjSize, DL, &TLI, Opts) && ObjSize > 1) {
+      if ((isa<GlobalVariable>(V) || isa<AllocaInst>(V)) &&
+          getObjectSize(V, ObjSize, DL, &TLI, Opts) && ObjSize > 1) {
         // The highest address the object can start is ObjSize bytes before the
         // end (unsigned max value). If this value is not a multiple of the
         // alignment, the last possible start value is the next lowest multiple
@@ -6830,7 +6830,7 @@ const ConstantRange &ScalarEvolution::getRangeRef(
         // because if they would there's no possible start address for the
         // object.
         APInt MaxVal = APInt::getMaxValue(BitWidth) - APInt(BitWidth, ObjSize);
-        uint64_t Align = GV->getAlign().valueOrOne().value();
+        uint64_t Align = U->getValue()->getPointerAlignment(DL).value();
         uint64_t Rem = MaxVal.urem(Align);
         MaxVal -= APInt(BitWidth, Rem);
         ConservativeResult = ConservativeResult.intersectWith(

diff  --git a/llvm/test/Analysis/ScalarEvolution/nsw.ll b/llvm/test/Analysis/ScalarEvolution/nsw.ll
index cf29a1b9c6141..046e4d0a79515 100644
--- a/llvm/test/Analysis/ScalarEvolution/nsw.ll
+++ b/llvm/test/Analysis/ScalarEvolution/nsw.ll
@@ -276,7 +276,7 @@ define void @test4(i32 %arg) {
 ; CHECK-LABEL: 'test4'
 ; CHECK-NEXT:  Classifying expressions for: @test4
 ; CHECK-NEXT:    %array = alloca [10 x i32], align 4
-; CHECK-NEXT:    --> %array U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT:    --> %array U: [0,-43) S: [-9223372036854775808,9223372036854775805)
 ; CHECK-NEXT:    %index = phi i32 [ %inc5, %for.body ], [ %arg, %entry ]
 ; CHECK-NEXT:    --> {%arg,+,1}<nsw><%for.body> U: full-set S: full-set Exits: (-1 + (10 smax (1 + %arg)<nsw>))<nsw> LoopDispositions: { %for.body: Computable }
 ; CHECK-NEXT:    %sub = add nsw i32 %index, -2

diff  --git a/llvm/test/Analysis/ScalarEvolution/sdiv.ll b/llvm/test/Analysis/ScalarEvolution/sdiv.ll
index 7f748f2b3b547..907cf9f606e76 100644
--- a/llvm/test/Analysis/ScalarEvolution/sdiv.ll
+++ b/llvm/test/Analysis/ScalarEvolution/sdiv.ll
@@ -8,9 +8,9 @@ define dso_local void @_Z4loopi(i32 %width) local_unnamed_addr #0 {
 ; CHECK-LABEL: '_Z4loopi'
 ; CHECK-NEXT:  Classifying expressions for: @_Z4loopi
 ; CHECK-NEXT:    %storage = alloca [2 x i32], align 4
-; CHECK-NEXT:    --> %storage U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT:    --> %storage U: [0,-11) S: [-9223372036854775808,9223372036854775805)
 ; CHECK-NEXT:    %0 = bitcast ptr %storage to ptr
-; CHECK-NEXT:    --> %storage U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT:    --> %storage U: [0,-11) S: [-9223372036854775808,9223372036854775805)
 ; CHECK-NEXT:    %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%for.cond> U: [0,-2147483648) S: [0,-2147483648) Exits: %width LoopDispositions: { %for.cond: Computable }
 ; CHECK-NEXT:    %rem = sdiv i32 %i.0, 2

diff  --git a/llvm/test/Analysis/ScalarEvolution/srem.ll b/llvm/test/Analysis/ScalarEvolution/srem.ll
index e90cd32630110..b6cfa8b6da74a 100644
--- a/llvm/test/Analysis/ScalarEvolution/srem.ll
+++ b/llvm/test/Analysis/ScalarEvolution/srem.ll
@@ -8,9 +8,9 @@ define dso_local void @_Z4loopi(i32 %width) local_unnamed_addr #0 {
 ; CHECK-LABEL: '_Z4loopi'
 ; CHECK-NEXT:  Classifying expressions for: @_Z4loopi
 ; CHECK-NEXT:    %storage = alloca [2 x i32], align 4
-; CHECK-NEXT:    --> %storage U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT:    --> %storage U: [0,-11) S: [-9223372036854775808,9223372036854775805)
 ; CHECK-NEXT:    %0 = bitcast ptr %storage to ptr
-; CHECK-NEXT:    --> %storage U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT:    --> %storage U: [0,-11) S: [-9223372036854775808,9223372036854775805)
 ; CHECK-NEXT:    %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
 ; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%for.cond> U: [0,-2147483648) S: [0,-2147483648) Exits: %width LoopDispositions: { %for.cond: Computable }
 ; CHECK-NEXT:    %rem = srem i32 %i.0, 2
@@ -18,7 +18,7 @@ define dso_local void @_Z4loopi(i32 %width) local_unnamed_addr #0 {
 ; CHECK-NEXT:    %idxprom = sext i32 %rem to i64
 ; CHECK-NEXT:    --> (zext i1 {false,+,true}<%for.cond> to i64) U: [0,2) S: [0,2) Exits: (zext i1 (trunc i32 %width to i1) to i64) LoopDispositions: { %for.cond: Computable }
 ; CHECK-NEXT:    %arrayidx = getelementptr inbounds [2 x i32], ptr %storage, i64 0, i64 %idxprom
-; CHECK-NEXT:    --> ((4 * (zext i1 {false,+,true}<%for.cond> to i64))<nuw><nsw> + %storage) U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * (zext i1 (trunc i32 %width to i1) to i64))<nuw><nsw> + %storage) LoopDispositions: { %for.cond: Computable }
+; CHECK-NEXT:    --> ((4 * (zext i1 {false,+,true}<%for.cond> to i64))<nuw><nsw> + %storage) U: [0,-7) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * (zext i1 (trunc i32 %width to i1) to i64))<nuw><nsw> + %storage) LoopDispositions: { %for.cond: Computable }
 ; CHECK-NEXT:    %1 = load i32, ptr %arrayidx, align 4
 ; CHECK-NEXT:    --> %1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
 ; CHECK-NEXT:    %call = call i32 @_Z3adji(i32 %1)


        


More information about the llvm-commits mailing list