Skip to content

Commit b569ec6

Browse files
authored
[SCCP] Infer nuw for gep nusw with non-negative offsets (#118819)
If the GEP is nusw/inbounds and has all-non-negative offsets infer nuw as well. This doesn't have measurable compile-time impact. Proof: https://alive2.llvm.org/ce/z/ihztLy
1 parent 055f1a7 commit b569ec6

File tree

8 files changed

+62
-55
lines changed

8 files changed

+62
-55
lines changed

clang/test/CodeGen/attr-counted-by.c

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct anon_struct {
7070
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
7171
// SANITIZE-WITH-ATTR: cont3:
7272
// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12
73-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]]
73+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]]
7474
// SANITIZE-WITH-ATTR-NEXT: store i32 [[VAL]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4:![0-9]+]]
7575
// SANITIZE-WITH-ATTR-NEXT: ret void
7676
//
@@ -282,46 +282,43 @@ size_t test3_bdos(struct annotated *p) {
282282
// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], 244
283283
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 252
284284
// SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = select i1 [[TMP2]], i32 [[TMP5]], i32 0
285-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]]
285+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]]
286286
// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]]
287-
// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD6:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4
288287
// SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1
289288
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM12:%.*]] = sext i32 [[ADD]] to i64
290-
// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD6]] to i64, !nosanitize [[META2]]
291-
// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp ult i64 [[IDXPROM12]], [[TMP6]], !nosanitize [[META2]]
292-
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP7]], label [[CONT19:%.*]], label [[HANDLER_OUT_OF_BOUNDS15:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
289+
// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp ult i64 [[IDXPROM12]], [[TMP0]], !nosanitize [[META2]]
290+
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label [[CONT19:%.*]], label [[HANDLER_OUT_OF_BOUNDS15:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
293291
// SANITIZE-WITH-ATTR: handler.out_of_bounds15:
294292
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM12]]) #[[ATTR8]], !nosanitize [[META2]]
295293
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
296294
// SANITIZE-WITH-ATTR: cont19:
297-
// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD6]], 3
298-
// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD6]], 2
299-
// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = add i32 [[TMP9]], 240
300-
// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = and i32 [[TMP10]], 252
301-
// SANITIZE-WITH-ATTR-NEXT: [[CONV8:%.*]] = select i1 [[TMP8]], i32 [[TMP11]], i32 0
302-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM12]]
295+
// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], 3
296+
// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = add i32 [[TMP3]], 240
297+
// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 252
298+
// SANITIZE-WITH-ATTR-NEXT: [[CONV8:%.*]] = select i1 [[TMP7]], i32 [[TMP9]], i32 0
299+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM12]]
303300
// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV8]], ptr [[ARRAYIDX17]], align 4, !tbaa [[TBAA4]]
304301
// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD21:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4
305302
// SANITIZE-WITH-ATTR-NEXT: [[ADD27:%.*]] = add nsw i32 [[INDEX]], 2
306303
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM28:%.*]] = sext i32 [[ADD27]] to i64
307-
// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD21]] to i64, !nosanitize [[META2]]
308-
// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = icmp ult i64 [[IDXPROM28]], [[TMP12]], !nosanitize [[META2]]
309-
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP13]], label [[CONT35:%.*]], label [[HANDLER_OUT_OF_BOUNDS31:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
304+
// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD21]] to i64, !nosanitize [[META2]]
305+
// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp ult i64 [[IDXPROM28]], [[TMP10]], !nosanitize [[META2]]
306+
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[CONT35:%.*]], label [[HANDLER_OUT_OF_BOUNDS31:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
310307
// SANITIZE-WITH-ATTR: handler.out_of_bounds31:
311308
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[IDXPROM28]]) #[[ATTR8]], !nosanitize [[META2]]
312309
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
313310
// SANITIZE-WITH-ATTR: cont35:
314-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM28]]
315-
// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = icmp sgt i32 [[FAM_IDX]], -1
316-
// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD21]] to i64
317-
// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = sext i32 [[FAM_IDX]] to i64
318-
// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = sub nsw i64 [[TMP15]], [[TMP16]]
319-
// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = icmp sgt i64 [[TMP17]], -1
320-
// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = and i1 [[TMP14]], [[TMP18]]
321-
// SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP17]] to i32
322-
// SANITIZE-WITH-ATTR-NEXT: [[TMP20:%.*]] = shl i32 [[DOTTR]], 2
323-
// SANITIZE-WITH-ATTR-NEXT: [[TMP21:%.*]] = and i32 [[TMP20]], 252
324-
// SANITIZE-WITH-ATTR-NEXT: [[CONV23:%.*]] = select i1 [[TMP19]], i32 [[TMP21]], i32 0
311+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM28]]
312+
// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = icmp sgt i32 [[FAM_IDX]], -1
313+
// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD21]] to i64
314+
// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = sext i32 [[FAM_IDX]] to i64
315+
// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = sub nsw i64 [[TMP13]], [[TMP14]]
316+
// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = icmp sgt i64 [[TMP15]], -1
317+
// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = and i1 [[TMP12]], [[TMP16]]
318+
// SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP15]] to i32
319+
// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = shl i32 [[DOTTR]], 2
320+
// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = and i32 [[TMP18]], 252
321+
// SANITIZE-WITH-ATTR-NEXT: [[CONV23:%.*]] = select i1 [[TMP17]], i32 [[TMP19]], i32 0
325322
// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV23]], ptr [[ARRAYIDX33]], align 4, !tbaa [[TBAA4]]
326323
// SANITIZE-WITH-ATTR-NEXT: ret void
327324
//
@@ -625,7 +622,7 @@ size_t test6_bdos(struct anon_struct *p) {
625622
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
626623
// SANITIZE-WITH-ATTR: cont7:
627624
// SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9
628-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]]
625+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]]
629626
// SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8:![0-9]+]]
630627
// SANITIZE-WITH-ATTR-NEXT: ret void
631628
//
@@ -698,7 +695,7 @@ size_t test7_bdos(struct union_of_fams *p) {
698695
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
699696
// SANITIZE-WITH-ATTR: cont7:
700697
// SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9
701-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]]
698+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]]
702699
// SANITIZE-WITH-ATTR-NEXT: store i8 [[DOT_COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]]
703700
// SANITIZE-WITH-ATTR-NEXT: ret void
704701
//
@@ -779,7 +776,7 @@ size_t test8_bdos(struct union_of_fams *p) {
779776
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
780777
// SANITIZE-WITH-ATTR: cont7:
781778
// SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12
782-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]]
779+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]]
783780
// SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]]
784781
// SANITIZE-WITH-ATTR-NEXT: ret void
785782
//
@@ -852,7 +849,7 @@ size_t test9_bdos(struct union_of_fams *p) {
852849
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
853850
// SANITIZE-WITH-ATTR: cont7:
854851
// SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12
855-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]]
852+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]]
856853
// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0)
857854
// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i32 [[NARROW]] to i8
858855
// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]]
@@ -939,7 +936,7 @@ size_t test10_bdos(struct union_of_fams *p) {
939936
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
940937
// SANITIZE-WITH-ATTR: cont3:
941938
// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12
942-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]]
939+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]]
943940
// SANITIZE-WITH-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]]
944941
// SANITIZE-WITH-ATTR-NEXT: ret void
945942
//
@@ -1130,7 +1127,7 @@ struct test13_bar {
11301127
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
11311128
// SANITIZE-WITH-ATTR: cont5:
11321129
// SANITIZE-WITH-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 16
1133-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]]
1130+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]]
11341131
// SANITIZE-WITH-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA15:![0-9]+]]
11351132
// SANITIZE-WITH-ATTR-NEXT: ret i32 0
11361133
//
@@ -1157,7 +1154,7 @@ struct test13_bar {
11571154
// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]]
11581155
// SANITIZE-WITHOUT-ATTR: cont5:
11591156
// SANITIZE-WITHOUT-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 16
1160-
// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]]
1157+
// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]]
11611158
// SANITIZE-WITHOUT-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA15:![0-9]+]]
11621159
// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 0
11631160
//
@@ -1518,7 +1515,7 @@ struct test26_foo {
15181515
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
15191516
// SANITIZE-WITH-ATTR: cont5:
15201517
// SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8
1521-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]]
1518+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]]
15221519
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]]
15231520
// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP2]]
15241521
//
@@ -1589,7 +1586,7 @@ struct test27_foo {
15891586
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
15901587
// SANITIZE-WITH-ATTR: cont3:
15911588
// SANITIZE-WITH-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 24
1592-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]]
1589+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x ptr], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]]
15931590
// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA19:![0-9]+]]
15941591
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM4:%.*]] = sext i32 [[J]] to i64
15951592
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [[STRUCT_TEST27_BAR:%.*]], ptr [[TMP2]], i64 [[IDXPROM4]]
@@ -1655,7 +1652,7 @@ struct test28_foo {
16551652
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
16561653
// SANITIZE-WITH-ATTR: cont17:
16571654
// SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12
1658-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]]
1655+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]]
16591656
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]]
16601657
// SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP5]]
16611658
//
@@ -1729,7 +1726,7 @@ struct annotated_struct_array {
17291726
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
17301727
// SANITIZE-WITH-ATTR: cont20:
17311728
// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12
1732-
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM15]]
1729+
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM15]]
17331730
// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0)
17341731
// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[TMP5]], 2
17351732
// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX18]], align 4, !tbaa [[TBAA4]]

llvm/lib/Transforms/Utils/SCCPSolver.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@ static bool refineInstruction(SCCPSolver &Solver,
147147
Changed = true;
148148
}
149149
}
150+
} else if (auto *GEP = dyn_cast<GetElementPtrInst>(&Inst)) {
151+
if (GEP->hasNoUnsignedWrap() || !GEP->hasNoUnsignedSignedWrap())
152+
return false;
153+
154+
if (all_of(GEP->indices(),
155+
[&](Value *V) { return GetRange(V).isAllNonNegative(); })) {
156+
GEP->setNoWrapFlags(GEP->getNoWrapFlags() |
157+
GEPNoWrapFlags::noUnsignedWrap());
158+
Changed = true;
159+
}
150160
}
151161

152162
return Changed;

llvm/test/Analysis/LazyCallGraph/blockaddress.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ define i32 @baz(i32 %y, i1 %b) {
77
; CHECK-NEXT: br i1 [[B:%.*]], label [[LAB:%.*]], label [[FOR_COND:%.*]]
88
; CHECK: for.cond:
99
; CHECK-NEXT: [[P_0:%.*]] = phi ptr [ null, [[FOR_COND]] ], [ blockaddress(@baz, [[LAB]]), [[ENTRY:%.*]] ]
10-
; CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i8, ptr [[P_0]], i64 1
10+
; CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[P_0]], i64 1
1111
; CHECK-NEXT: br label [[FOR_COND]]
1212
; CHECK: lab:
1313
; CHECK-NEXT: ret i32 0

llvm/test/Transforms/SCCP/conditions-iter-order.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ define internal ptr @spam(ptr %arg) {
1313
; CHECK-NEXT: [[TMP:%.*]] = call ptr @malloc(i64 10368)
1414
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARG:%.*]], align 8
1515
; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP5]], 1
16-
; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i32 1
16+
; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw i32, ptr [[ARG]], i32 1
1717
; CHECK-NEXT: [[TMP10:%.*]] = icmp ne ptr [[TMP7]], null
1818
; CHECK-NEXT: br i1 [[TMP10]], label [[BB17:%.*]], label [[BB13:%.*]]
1919
; CHECK: bb13:
20-
; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i32 2
20+
; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw i32, ptr [[ARG]], i32 2
2121
; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 8
2222
; CHECK-NEXT: [[TMP16:%.*]] = add i32 [[TMP15]], 1
2323
; CHECK-NEXT: br label [[BB30:%.*]]
2424
; CHECK: bb17:
2525
; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i32 [[TMP6]], [[TMP5]]
26-
; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i32 3
26+
; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw i32, ptr [[ARG]], i32 3
2727
; CHECK-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 8
2828
; CHECK-NEXT: br i1 [[TMP18]], label [[BB30]], label [[BB13]]
2929
; CHECK: bb30:

llvm/test/Transforms/SCCP/gep-nuw.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ define ptr @gep_nusw_nneg(ptr %p, i32 %x, i32 %y) {
66
; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {
77
; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X]] to i64
88
; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y]] to i64
9-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr nusw [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
9+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr nusw nuw [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
1010
; CHECK-NEXT: ret ptr [[GEP]]
1111
;
1212
%x.ext = zext i32 %x to i64
@@ -20,7 +20,7 @@ define ptr @gep_inbounds_nneg(ptr %p, i32 %x, i32 %y) {
2020
; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {
2121
; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X]] to i64
2222
; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y]] to i64
23-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
23+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
2424
; CHECK-NEXT: ret ptr [[GEP]]
2525
;
2626
%x.ext = zext i32 %x to i64

llvm/test/Transforms/SCCP/ipsccp-ssa-copy-nested-conds.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ define i32 @check(ptr %node) {
1515
; CHECK: if.end:
1616
; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[NODE]], align 8
1717
; CHECK-NEXT: [[CALL:%.*]] = call i32 @check(ptr [[TMP0]])
18-
; CHECK-NEXT: [[RIGHT:%.*]] = getelementptr inbounds [[STRUCT_NODE:%.*]], ptr [[NODE]], i32 0, i32 1
18+
; CHECK-NEXT: [[RIGHT:%.*]] = getelementptr inbounds nuw [[STRUCT_NODE:%.*]], ptr [[NODE]], i32 0, i32 1
1919
; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RIGHT]], align 8
2020
; CHECK-NEXT: [[CALL1:%.*]] = call i32 @check(ptr [[TMP1]])
2121
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[RIGHT]], align 8
22-
; CHECK-NEXT: [[HEIGHT:%.*]] = getelementptr inbounds [[STRUCT_NODE]], ptr [[TMP2]], i32 0, i32 2
22+
; CHECK-NEXT: [[HEIGHT:%.*]] = getelementptr inbounds nuw [[STRUCT_NODE]], ptr [[TMP2]], i32 0, i32 2
2323
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[HEIGHT]], align 4
2424
; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i32 [[TMP3]], [[CALL1]]
2525
; CHECK-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]]

llvm/test/Transforms/SCCP/pr45185-range-predinfo.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ define void @spam(ptr %arg) {
88
; CHECK-SAME: ptr [[ARG:%.*]]) {
99
; CHECK-NEXT: [[BB:.*:]]
1010
; CHECK-NEXT: call void @blam(i32 0, ptr nonnull [[ARG]])
11-
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [4 x [24 x float]], ptr [[ARG]], i64 0, i64 1, i64 0
11+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [4 x [24 x float]], ptr [[ARG]], i64 0, i64 1, i64 0
1212
; CHECK-NEXT: call void @blam(i32 1, ptr nonnull [[TMP1]])
13-
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [4 x [24 x float]], ptr [[ARG]], i64 0, i64 2, i64 0
13+
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw [4 x [24 x float]], ptr [[ARG]], i64 0, i64 2, i64 0
1414
; CHECK-NEXT: call void @blam(i32 2, ptr nonnull [[TMP2]])
1515
; CHECK-NEXT: ret void
1616
;

0 commit comments

Comments
 (0)