Skip to content

Commit e2cfd34

Browse files
committed
LAA: check nusw on GEP in place of inbounds
With the introduction of the nusw flag in GEPNoWrapFlags, it should be safe to weaken the check in LoopAccessAnalysis to just check the nusw flag on the GEP, instead of inbounds.
1 parent bdf241c commit e2cfd34

File tree

2 files changed

+35
-35
lines changed

2 files changed

+35
-35
lines changed

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,7 @@ static bool isNoWrapAddRec(Value *Ptr, const SCEVAddRecExpr *AR,
14141414

14151415
// The arithmetic implied by an inbounds GEP can't overflow.
14161416
const auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1417-
if (!GEP || !GEP->isInBounds())
1417+
if (!GEP || !GEP->hasNoUnsignedSignedWrap())
14181418
return false;
14191419

14201420
// Make sure there is only one non-const index and analyze that.
@@ -1521,7 +1521,7 @@ llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
15211521
// and any memory access dependent on it would be immediate UB
15221522
// when executed.
15231523
if (auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1524-
GEP && GEP->isInBounds() && (Stride == 1 || Stride == -1))
1524+
GEP && GEP->hasNoUnsignedSignedWrap() && (Stride == 1 || Stride == -1))
15251525
return Stride;
15261526

15271527
// If the null pointer is undefined, then a access sequence which would

llvm/test/Analysis/LoopAccessAnalysis/symbolic-stride.ll

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ define void @single_stride(ptr noalias %A, ptr noalias %B, i64 %N, i64 %stride)
2323
; CHECK-NEXT: Equal predicate: %stride == 1
2424
; CHECK-EMPTY:
2525
; CHECK-NEXT: Expressions re-written:
26-
; CHECK-NEXT: [PSE] %gep.A = getelementptr inbounds i32, ptr %A, i64 %mul:
26+
; CHECK-NEXT: [PSE] %gep.A = getelementptr nusw i32, ptr %A, i64 %mul:
2727
; CHECK-NEXT: {%A,+,(4 * %stride)}<%loop>
2828
; CHECK-NEXT: --> {%A,+,4}<%loop>
2929
;
@@ -33,13 +33,13 @@ entry:
3333
loop:
3434
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
3535
%mul = mul i64 %iv, %stride
36-
%gep.A = getelementptr inbounds i32, ptr %A, i64 %mul
36+
%gep.A = getelementptr nusw i32, ptr %A, i64 %mul
3737
%load = load i32, ptr %gep.A, align 4
38-
%gep.B = getelementptr inbounds i32, ptr %B, i64 %iv
38+
%gep.B = getelementptr nusw i32, ptr %B, i64 %iv
3939
%load_1 = load i32, ptr %gep.B, align 4
4040
%add = add i32 %load_1, %load
4141
%iv.next = add nuw nsw i64 %iv, 1
42-
%gep.A.next = getelementptr inbounds i32, ptr %A, i64 %iv.next
42+
%gep.A.next = getelementptr nusw i32, ptr %A, i64 %iv.next
4343
store i32 %add, ptr %gep.A.next, align 4
4444
%exitcond = icmp eq i64 %iv.next, %N
4545
br i1 %exitcond, label %exit, label %loop
@@ -67,7 +67,7 @@ define void @single_stride_struct(ptr noalias %A, ptr noalias %B, i64 %N, i64 %s
6767
; CHECK-NEXT: Equal predicate: %stride == 1
6868
; CHECK-EMPTY:
6969
; CHECK-NEXT: Expressions re-written:
70-
; CHECK-NEXT: [PSE] %gep.A = getelementptr inbounds { i32, i8 }, ptr %A, i64 %mul:
70+
; CHECK-NEXT: [PSE] %gep.A = getelementptr nusw { i32, i8 }, ptr %A, i64 %mul:
7171
; CHECK-NEXT: {%A,+,(8 * %stride)}<%loop>
7272
; CHECK-NEXT: --> {%A,+,8}<%loop>
7373
;
@@ -77,16 +77,16 @@ entry:
7777
loop:
7878
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
7979
%mul = mul i64 %iv, %stride
80-
%gep.A = getelementptr inbounds { i32, i8 }, ptr %A, i64 %mul
80+
%gep.A = getelementptr nusw { i32, i8 }, ptr %A, i64 %mul
8181
%load = load { i32, i8 }, ptr %gep.A, align 4
82-
%gep.B = getelementptr inbounds { i32, i8 }, ptr %B, i64 %iv
82+
%gep.B = getelementptr nusw { i32, i8 }, ptr %B, i64 %iv
8383
%load_1 = load { i32, i8 }, ptr %gep.B, align 4
8484
%v1 = extractvalue { i32, i8 } %load, 0
8585
%v2 = extractvalue { i32, i8} %load_1, 0
8686
%add = add i32 %v1, %v2
8787
%ins = insertvalue { i32, i8 } undef, i32 %add, 0
8888
%iv.next = add nuw nsw i64 %iv, 1
89-
%gep.A.next = getelementptr inbounds { i32, i8 }, ptr %A, i64 %iv.next
89+
%gep.A.next = getelementptr nusw { i32, i8 }, ptr %A, i64 %iv.next
9090
store { i32, i8 } %ins, ptr %gep.A.next, align 4
9191
%exitcond = icmp eq i64 %iv.next, %N
9292
br i1 %exitcond, label %exit, label %loop
@@ -105,7 +105,7 @@ define void @single_stride_castexpr(i32 %offset, ptr %src, ptr %dst, i1 %cond) {
105105
; CHECK-NEXT: Comparing group ([[GRP1:0x[0-9a-f]+]]):
106106
; CHECK-NEXT: %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2
107107
; CHECK-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]):
108-
; CHECK-NEXT: %gep.src = getelementptr inbounds i32, ptr %src, i32 %iv.3
108+
; CHECK-NEXT: %gep.src = getelementptr nusw i32, ptr %src, i32 %iv.3
109109
; CHECK-NEXT: Grouped accesses:
110110
; CHECK-NEXT: Group [[GRP1]]:
111111
; CHECK-NEXT: (Low: ((4 * %iv.1) + %dst) High: (804 + (4 * %iv.1) + %dst))
@@ -144,7 +144,7 @@ outer.header:
144144
inner.loop:
145145
%iv.2 = phi i64 [ %iv.1, %outer.header ], [ %iv.2.next, %inner.loop ]
146146
%iv.3 = phi i32 [ 0, %outer.header ], [ %iv.3.next, %inner.loop ]
147-
%gep.src = getelementptr inbounds i32, ptr %src, i32 %iv.3
147+
%gep.src = getelementptr nusw i32, ptr %src, i32 %iv.3
148148
%load = load i32, ptr %gep.src, align 8
149149
%gep.dst = getelementptr i32, ptr %dst, i64 %iv.2
150150
store i32 %load, ptr %gep.dst, align 8
@@ -167,7 +167,7 @@ define void @single_stride_castexpr_multiuse(i32 %offset, ptr %src, ptr %dst, i1
167167
; CHECK-NEXT: Comparing group ([[GRP3:0x[0-9a-f]+]]):
168168
; CHECK-NEXT: %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2
169169
; CHECK-NEXT: Against group ([[GRP4:0x[0-9a-f]+]]):
170-
; CHECK-NEXT: %gep.src = getelementptr inbounds i32, ptr %src, i64 %iv.3
170+
; CHECK-NEXT: %gep.src = getelementptr nusw i32, ptr %src, i64 %iv.3
171171
; CHECK-NEXT: Grouped accesses:
172172
; CHECK-NEXT: Group [[GRP3]]:
173173
; CHECK-NEXT: (Low: ((4 * %iv.1) + %dst) High: (804 + (4 * %iv.1) + (-4 * (zext i32 %offset to i64))<nsw> + %dst))
@@ -181,7 +181,7 @@ define void @single_stride_castexpr_multiuse(i32 %offset, ptr %src, ptr %dst, i1
181181
; CHECK-NEXT: Equal predicate: %offset == 1
182182
; CHECK-EMPTY:
183183
; CHECK-NEXT: Expressions re-written:
184-
; CHECK-NEXT: [PSE] %gep.src = getelementptr inbounds i32, ptr %src, i64 %iv.3:
184+
; CHECK-NEXT: [PSE] %gep.src = getelementptr nusw i32, ptr %src, i64 %iv.3:
185185
; CHECK-NEXT: {((4 * (zext i32 %offset to i64))<nuw><nsw> + %src),+,4}<%inner.loop>
186186
; CHECK-NEXT: --> {(4 + %src),+,4}<%inner.loop>
187187
; CHECK-NEXT: [PSE] %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2:
@@ -210,7 +210,7 @@ outer.header:
210210
inner.loop:
211211
%iv.2 = phi i64 [ %iv.1, %outer.header ], [ %iv.2.next, %inner.loop ]
212212
%iv.3 = phi i64 [ %offset.zext, %outer.header ], [ %iv.3.next, %inner.loop ]
213-
%gep.src = getelementptr inbounds i32, ptr %src, i64 %iv.3
213+
%gep.src = getelementptr nusw i32, ptr %src, i64 %iv.3
214214
%load = load i32, ptr %gep.src, align 8
215215
%gep.dst = getelementptr i32, ptr %dst, i64 %iv.2
216216
store i32 %load, ptr %gep.dst, align 8
@@ -291,10 +291,10 @@ define void @two_strides(ptr noalias %A, ptr noalias %B, i64 %N, i64 %stride.1,
291291
; CHECK-NEXT: Equal predicate: %stride.1 == 1
292292
; CHECK-EMPTY:
293293
; CHECK-NEXT: Expressions re-written:
294-
; CHECK-NEXT: [PSE] %gep.A = getelementptr inbounds i32, ptr %A, i64 %mul:
294+
; CHECK-NEXT: [PSE] %gep.A = getelementptr nusw i32, ptr %A, i64 %mul:
295295
; CHECK-NEXT: {%A,+,(4 * %stride.1)}<%loop>
296296
; CHECK-NEXT: --> {%A,+,4}<%loop>
297-
; CHECK-NEXT: [PSE] %gep.A.next = getelementptr inbounds i32, ptr %A, i64 %mul.2:
297+
; CHECK-NEXT: [PSE] %gep.A.next = getelementptr nusw i32, ptr %A, i64 %mul.2:
298298
; CHECK-NEXT: {((4 * %stride.2) + %A),+,(4 * %stride.2)}<%loop>
299299
; CHECK-NEXT: --> {(4 + %A),+,4}<%loop>
300300
;
@@ -304,14 +304,14 @@ entry:
304304
loop:
305305
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
306306
%mul = mul i64 %iv, %stride.1
307-
%gep.A = getelementptr inbounds i32, ptr %A, i64 %mul
307+
%gep.A = getelementptr nusw i32, ptr %A, i64 %mul
308308
%load = load i32, ptr %gep.A, align 4
309-
%gep.B = getelementptr inbounds i32, ptr %B, i64 %iv
309+
%gep.B = getelementptr nusw i32, ptr %B, i64 %iv
310310
%load_1 = load i32, ptr %gep.B, align 4
311311
%add = add i32 %load_1, %load
312312
%iv.next = add nuw nsw i64 %iv, 1
313313
%mul.2 = mul i64 %iv.next, %stride.2
314-
%gep.A.next = getelementptr inbounds i32, ptr %A, i64 %mul.2
314+
%gep.A.next = getelementptr nusw i32, ptr %A, i64 %mul.2
315315
store i32 %add, ptr %gep.A.next, align 4
316316
%exitcond = icmp eq i64 %iv.next, %N
317317
br i1 %exitcond, label %exit, label %loop
@@ -344,13 +344,13 @@ entry:
344344
loop:
345345
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
346346
%mul = mul i64 %iv, %stride
347-
%gep.A = getelementptr inbounds i32, ptr %A, i64 %mul
347+
%gep.A = getelementptr nusw i32, ptr %A, i64 %mul
348348
%load = load i32, ptr %gep.A, align 4
349-
%gep.B = getelementptr inbounds i32, ptr %B, i64 %iv
349+
%gep.B = getelementptr nusw i32, ptr %B, i64 %iv
350350
%load_1 = load i32, ptr %gep.B, align 4
351351
%add = add i32 %load_1, %load
352352
%iv.next = add nuw nsw i64 %iv, 1
353-
%gep.A.next = getelementptr inbounds i32, ptr %A, i64 %iv.next
353+
%gep.A.next = getelementptr nusw i32, ptr %A, i64 %iv.next
354354
store i32 %add, ptr %gep.A.next, align 4
355355
%exitcond = icmp eq i64 %iv.next, %stride
356356
br i1 %exitcond, label %exit, label %loop
@@ -372,7 +372,7 @@ define void @unknown_stride_equalto_tc(i32 %N, ptr %A, ptr %B, i32 %j) {
372372
; CHECK-NEXT: Comparing group ([[GRP5:0x[0-9a-f]+]]):
373373
; CHECK-NEXT: ptr %A
374374
; CHECK-NEXT: Against group ([[GRP6:0x[0-9a-f]+]]):
375-
; CHECK-NEXT: %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add
375+
; CHECK-NEXT: %arrayidx = getelementptr nusw i16, ptr %B, i32 %add
376376
; CHECK-NEXT: Grouped accesses:
377377
; CHECK-NEXT: Group [[GRP5]]:
378378
; CHECK-NEXT: (Low: %A High: (4 + %A))
@@ -386,7 +386,7 @@ define void @unknown_stride_equalto_tc(i32 %N, ptr %A, ptr %B, i32 %j) {
386386
; CHECK-NEXT: {%j,+,%N}<%loop> Added Flags: <nssw>
387387
; CHECK-EMPTY:
388388
; CHECK-NEXT: Expressions re-written:
389-
; CHECK-NEXT: [PSE] %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add:
389+
; CHECK-NEXT: [PSE] %arrayidx = getelementptr nusw i16, ptr %B, i32 %add:
390390
; CHECK-NEXT: ((2 * (sext i32 {%j,+,%N}<%loop> to i64))<nsw> + %B)
391391
; CHECK-NEXT: --> {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (sext i32 %N to i64))<nsw>}<%loop>
392392
;
@@ -398,7 +398,7 @@ loop:
398398
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
399399
%mul = mul i32 %iv, %N
400400
%add = add i32 %mul, %j
401-
%arrayidx = getelementptr inbounds i16, ptr %B, i32 %add
401+
%arrayidx = getelementptr nusw i16, ptr %B, i32 %add
402402
%load = load i16, ptr %arrayidx
403403
%sext = sext i16 %load to i32
404404
store i32 %sext, ptr %A
@@ -423,7 +423,7 @@ define void @unknown_stride_equalto_zext_tc(i16 zeroext %N, ptr %A, ptr %B, i32
423423
; CHECK-NEXT: Comparing group ([[GRP7:0x[0-9a-f]+]]):
424424
; CHECK-NEXT: ptr %A
425425
; CHECK-NEXT: Against group ([[GRP8:0x[0-9a-f]+]]):
426-
; CHECK-NEXT: %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add
426+
; CHECK-NEXT: %arrayidx = getelementptr nusw i16, ptr %B, i32 %add
427427
; CHECK-NEXT: Grouped accesses:
428428
; CHECK-NEXT: Group [[GRP7]]:
429429
; CHECK-NEXT: (Low: %A High: (4 + %A))
@@ -437,7 +437,7 @@ define void @unknown_stride_equalto_zext_tc(i16 zeroext %N, ptr %A, ptr %B, i32
437437
; CHECK-NEXT: {%j,+,(zext i16 %N to i32)}<nw><%loop> Added Flags: <nssw>
438438
; CHECK-EMPTY:
439439
; CHECK-NEXT: Expressions re-written:
440-
; CHECK-NEXT: [PSE] %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add:
440+
; CHECK-NEXT: [PSE] %arrayidx = getelementptr nusw i16, ptr %B, i32 %add:
441441
; CHECK-NEXT: ((2 * (sext i32 {%j,+,(zext i16 %N to i32)}<nw><%loop> to i64))<nsw> + %B)
442442
; CHECK-NEXT: --> {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (zext i16 %N to i64))<nuw><nsw>}<%loop>
443443
;
@@ -450,7 +450,7 @@ loop:
450450
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
451451
%mul = mul nuw i32 %iv, %N.ext
452452
%add = add i32 %mul, %j
453-
%arrayidx = getelementptr inbounds i16, ptr %B, i32 %add
453+
%arrayidx = getelementptr nusw i16, ptr %B, i32 %add
454454
%load = load i16, ptr %arrayidx
455455
%sext = sext i16 %load to i32
456456
store i32 %sext, ptr %A
@@ -474,7 +474,7 @@ define void @unknown_stride_equalto_sext_tc(i16 %N, ptr %A, ptr %B, i32 %j) {
474474
; CHECK-NEXT: Comparing group ([[GRP9:0x[0-9a-f]+]]):
475475
; CHECK-NEXT: ptr %A
476476
; CHECK-NEXT: Against group ([[GRP10:0x[0-9a-f]+]]):
477-
; CHECK-NEXT: %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add
477+
; CHECK-NEXT: %arrayidx = getelementptr nusw i16, ptr %B, i32 %add
478478
; CHECK-NEXT: Grouped accesses:
479479
; CHECK-NEXT: Group [[GRP9]]:
480480
; CHECK-NEXT: (Low: %A High: (4 + %A))
@@ -488,7 +488,7 @@ define void @unknown_stride_equalto_sext_tc(i16 %N, ptr %A, ptr %B, i32 %j) {
488488
; CHECK-NEXT: {%j,+,(sext i16 %N to i32)}<nw><%loop> Added Flags: <nssw>
489489
; CHECK-EMPTY:
490490
; CHECK-NEXT: Expressions re-written:
491-
; CHECK-NEXT: [PSE] %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add:
491+
; CHECK-NEXT: [PSE] %arrayidx = getelementptr nusw i16, ptr %B, i32 %add:
492492
; CHECK-NEXT: ((2 * (sext i32 {%j,+,(sext i16 %N to i32)}<nw><%loop> to i64))<nsw> + %B)
493493
; CHECK-NEXT: --> {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (sext i16 %N to i64))<nsw>}<%loop>
494494
;
@@ -501,7 +501,7 @@ loop:
501501
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
502502
%mul = mul nuw i32 %iv, %N.ext
503503
%add = add i32 %mul, %j
504-
%arrayidx = getelementptr inbounds i16, ptr %B, i32 %add
504+
%arrayidx = getelementptr nusw i16, ptr %B, i32 %add
505505
%load = load i16, ptr %arrayidx
506506
%sext = sext i16 %load to i32
507507
store i32 %sext, ptr %A
@@ -525,7 +525,7 @@ define void @unknown_stride_equalto_trunc_tc(i64 %N, ptr %A, ptr %B, i32 %j) {
525525
; CHECK-NEXT: Comparing group ([[GRP11:0x[0-9a-f]+]]):
526526
; CHECK-NEXT: ptr %A
527527
; CHECK-NEXT: Against group ([[GRP12:0x[0-9a-f]+]]):
528-
; CHECK-NEXT: %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add
528+
; CHECK-NEXT: %arrayidx = getelementptr nusw i16, ptr %B, i32 %add
529529
; CHECK-NEXT: Grouped accesses:
530530
; CHECK-NEXT: Group [[GRP11]]:
531531
; CHECK-NEXT: (Low: %A High: (4 + %A))
@@ -539,7 +539,7 @@ define void @unknown_stride_equalto_trunc_tc(i64 %N, ptr %A, ptr %B, i32 %j) {
539539
; CHECK-NEXT: {%j,+,(trunc i64 %N to i32)}<nw><%loop> Added Flags: <nssw>
540540
; CHECK-EMPTY:
541541
; CHECK-NEXT: Expressions re-written:
542-
; CHECK-NEXT: [PSE] %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add:
542+
; CHECK-NEXT: [PSE] %arrayidx = getelementptr nusw i16, ptr %B, i32 %add:
543543
; CHECK-NEXT: ((2 * (sext i32 {%j,+,(trunc i64 %N to i32)}<nw><%loop> to i64))<nsw> + %B)
544544
; CHECK-NEXT: --> {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (sext i32 (trunc i64 %N to i32) to i64))<nsw>}<%loop>
545545
;
@@ -552,7 +552,7 @@ loop:
552552
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
553553
%mul = mul nuw i32 %iv, %N.trunc
554554
%add = add i32 %mul, %j
555-
%arrayidx = getelementptr inbounds i16, ptr %B, i32 %add
555+
%arrayidx = getelementptr nusw i16, ptr %B, i32 %add
556556
%load = load i16, ptr %arrayidx
557557
%sext = sext i16 %load to i32
558558
store i32 %sext, ptr %A

0 commit comments

Comments
 (0)