Skip to content

Commit

Permalink
[SCEV] Use object size for allocas as well
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikic committed Jun 23, 2023
1 parent 6555b5d commit 406e9c9
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 11 deletions.
10 changes: 5 additions & 5 deletions llvm/lib/Analysis/ScalarEvolution.cpp
Expand Up @@ -6815,22 +6815,22 @@ 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
// of the alignment. Note: The computations below cannot overflow,
// 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(
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Analysis/ScalarEvolution/nsw.ll
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Analysis/ScalarEvolution/sdiv.ll
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/Analysis/ScalarEvolution/srem.ll
Expand Up @@ -8,17 +8,17 @@ 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
; CHECK-NEXT: --> (zext i1 {false,+,true}<%for.cond> to i32) U: [0,2) S: [0,2) Exits: (zext i1 (trunc i32 %width to i1) to i32) LoopDispositions: { %for.cond: Computable }
; 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)
Expand Down

0 comments on commit 406e9c9

Please sign in to comment.