Skip to content

Commit 29b4726

Browse files
david-armcjdb
authored andcommitted
[Analysis] Teach ScalarEvolution::getRangeRef about more dereferenceable objects (#104778)
Whilst dealing with review comments on #96752 I discovered that SCEV does not know about the dereferenceable attribute on function arguments so I have updated getRangeRef to make use of it by calling getPointerDereferenceableBytes.
1 parent 2afdbf3 commit 29b4726

File tree

4 files changed

+49
-14
lines changed

4 files changed

+49
-14
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

+8-10
Original file line numberDiff line numberDiff line change
@@ -6855,20 +6855,18 @@ const ConstantRange &ScalarEvolution::getRangeRef(
68556855
if (U->getType()->isPointerTy() && SignHint == HINT_RANGE_UNSIGNED) {
68566856
// Strengthen the range if the underlying IR value is a
68576857
// global/alloca/heap allocation using the size of the object.
6858-
ObjectSizeOpts Opts;
6859-
Opts.RoundToAlign = false;
6860-
Opts.NullIsUnknownSize = true;
6861-
uint64_t ObjSize;
6862-
if ((isa<GlobalVariable>(V) || isa<AllocaInst>(V) ||
6863-
isAllocationFn(V, &TLI)) &&
6864-
getObjectSize(V, ObjSize, DL, &TLI, Opts) && ObjSize > 1) {
6865-
// The highest address the object can start is ObjSize bytes before the
6866-
// end (unsigned max value). If this value is not a multiple of the
6858+
bool CanBeNull, CanBeFreed;
6859+
uint64_t DerefBytes =
6860+
V->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
6861+
if (DerefBytes > 1) {
6862+
// The highest address the object can start is DerefBytes bytes before
6863+
// the end (unsigned max value). If this value is not a multiple of the
68676864
// alignment, the last possible start value is the next lowest multiple
68686865
// of the alignment. Note: The computations below cannot overflow,
68696866
// because if they would there's no possible start address for the
68706867
// object.
6871-
APInt MaxVal = APInt::getMaxValue(BitWidth) - APInt(BitWidth, ObjSize);
6868+
APInt MaxVal =
6869+
APInt::getMaxValue(BitWidth) - APInt(BitWidth, DerefBytes);
68726870
uint64_t Align = U->getValue()->getPointerAlignment(DL).value();
68736871
uint64_t Rem = MaxVal.urem(Align);
68746872
MaxVal -= APInt(BitWidth, Rem);

llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ define void @test_05(i32 %N) {
457457
; CHECK-NEXT: %"alloca point" = bitcast i32 0 to i32
458458
; CHECK-NEXT: --> 0 U: [0,1) S: [0,1)
459459
; CHECK-NEXT: %tmp = getelementptr [1000 x i32], ptr @A, i32 0, i32 %i.0
460-
; CHECK-NEXT: --> {(8 + @A)<nuw><nsw>,+,4}<nw><%bb3> U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: (408 + @A) LoopDispositions: { %bb3: Computable }
460+
; CHECK-NEXT: --> {(8 + @A)<nuw><nsw>,+,4}<nw><%bb3> U: [40,-3623) S: [-9223372036854775808,9223372036854775805) Exits: (408 + @A)<nuw> LoopDispositions: { %bb3: Computable }
461461
; CHECK-NEXT: %tmp2 = add i32 %i.0, 1
462462
; CHECK-NEXT: --> {3,+,1}<nuw><nsw><%bb3> U: [3,104) S: [3,104) Exits: 103 LoopDispositions: { %bb3: Computable }
463463
; CHECK-NEXT: %i.0 = phi i32 [ 2, %entry ], [ %tmp2, %bb ]

llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll

+39-2
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,15 @@ define void @f3(ptr %x_addr, ptr %y_addr, ptr %tmp_addr) {
183183
; CHECK-NEXT: %s3.zext = zext i8 %s3 to i16
184184
; CHECK-NEXT: --> (1 + (zext i8 (4 + (32 * %x) + (36 * %y)) to i16))<nuw><nsw> U: [1,254) S: [1,257)
185185
; CHECK-NEXT: %ptr = bitcast ptr @z_addr to ptr
186-
; CHECK-NEXT: --> @z_addr U: [0,-3) S: [-9223372036854775808,9223372036854775805)
186+
; CHECK-NEXT: --> @z_addr U: [4,-19) S: [-9223372036854775808,9223372036854775805)
187187
; CHECK-NEXT: %int0 = ptrtoint ptr %ptr to i32
188188
; CHECK-NEXT: --> (trunc i64 (ptrtoint ptr @z_addr to i64) to i32) U: [0,-3) S: [-2147483648,2147483645)
189189
; CHECK-NEXT: %int5 = add i32 %int0, 5
190190
; CHECK-NEXT: --> (5 + (trunc i64 (ptrtoint ptr @z_addr to i64) to i32)) U: [5,2) S: [-2147483643,-2147483646)
191191
; CHECK-NEXT: %int.zext = zext i32 %int5 to i64
192192
; CHECK-NEXT: --> (1 + (zext i32 (4 + (trunc i64 (ptrtoint ptr @z_addr to i64) to i32)) to i64))<nuw><nsw> U: [1,4294967294) S: [1,4294967297)
193193
; CHECK-NEXT: %ptr_noalign = bitcast ptr @z_addr_noalign to ptr
194-
; CHECK-NEXT: --> @z_addr_noalign U: full-set S: full-set
194+
; CHECK-NEXT: --> @z_addr_noalign U: [1,-16) S: full-set
195195
; CHECK-NEXT: %int0_na = ptrtoint ptr %ptr_noalign to i32
196196
; CHECK-NEXT: --> (trunc i64 (ptrtoint ptr @z_addr_noalign to i64) to i32) U: full-set S: full-set
197197
; CHECK-NEXT: %int5_na = add i32 %int0_na, 5
@@ -362,3 +362,40 @@ loop:
362362
exit2:
363363
ret i1 false
364364
}
365+
366+
367+
define void @dereferenceable_arg(ptr dereferenceable(128) %len_addr, ptr dereferenceable(128) align(8) %len_addr2, ptr dereferenceable(13) align(1) %len_addr3) {
368+
; CHECK-LABEL: 'dereferenceable_arg'
369+
; CHECK-NEXT: Classifying expressions for: @dereferenceable_arg
370+
; CHECK-NEXT: %ptr = bitcast ptr %len_addr to ptr
371+
; CHECK-NEXT: --> %len_addr U: [1,-128) S: full-set
372+
; CHECK-NEXT: %ptr2 = bitcast ptr %len_addr2 to ptr
373+
; CHECK-NEXT: --> %len_addr2 U: [8,-135) S: [-9223372036854775808,9223372036854775801)
374+
; CHECK-NEXT: %ptr3 = bitcast ptr %len_addr3 to ptr
375+
; CHECK-NEXT: --> %len_addr3 U: [1,-13) S: full-set
376+
; CHECK-NEXT: Determining loop execution counts for: @dereferenceable_arg
377+
;
378+
entry:
379+
%ptr = bitcast ptr %len_addr to ptr
380+
%ptr2 = bitcast ptr %len_addr2 to ptr
381+
%ptr3 = bitcast ptr %len_addr3 to ptr
382+
383+
ret void
384+
}
385+
386+
387+
define void @dereferenceable_or_null_arg(ptr dereferenceable_or_null(128) %len_addr, ptr dereferenceable_or_null(128) align(8) %len_addr2) {
388+
; CHECK-LABEL: 'dereferenceable_or_null_arg'
389+
; CHECK-NEXT: Classifying expressions for: @dereferenceable_or_null_arg
390+
; CHECK-NEXT: %ptr = bitcast ptr %len_addr to ptr
391+
; CHECK-NEXT: --> %len_addr U: [0,-128) S: full-set
392+
; CHECK-NEXT: %ptr2 = bitcast ptr %len_addr2 to ptr
393+
; CHECK-NEXT: --> %len_addr2 U: [0,-135) S: [-9223372036854775808,9223372036854775801)
394+
; CHECK-NEXT: Determining loop execution counts for: @dereferenceable_or_null_arg
395+
;
396+
entry:
397+
%ptr = bitcast ptr %len_addr to ptr
398+
%ptr2 = bitcast ptr %len_addr2 to ptr
399+
400+
ret void
401+
}

llvm/test/Transforms/PhaseOrdering/scev-custom-dl.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ define void @test_range_ref1a(i32 %x) {
112112
; CHECK-NEXT: %i.01.0 = phi i32 [ 100, %entry ], [ %tmp4, %bb ]
113113
; CHECK-NEXT: --> {100,+,-1}<nsw><%bb> U: [0,101) S: [0,101) Exits: 0 LoopDispositions: { %bb: Computable }
114114
; CHECK-NEXT: %tmp1 = getelementptr [101 x i32], ptr @array, i32 0, i32 %i.01.0
115-
; CHECK-NEXT: --> {(400 + @array),+,-4}<nw><%bb> U: [0,-3) S: [-2147483648,2147483645) Exits: @array LoopDispositions: { %bb: Computable }
115+
; CHECK-NEXT: --> {(400 + @array)<nuw>,+,-4}<nw><%bb> U: [0,-3) S: [-2147483648,2147483645) Exits: @array LoopDispositions: { %bb: Computable }
116116
; CHECK-NEXT: %tmp4 = add nsw i32 %i.01.0, -1
117117
; CHECK-NEXT: --> {99,+,-1}<nsw><%bb> U: [-1,100) S: [-1,100) Exits: -1 LoopDispositions: { %bb: Computable }
118118
; CHECK-NEXT: Determining loop execution counts for: @test_range_ref1a

0 commit comments

Comments
 (0)