Skip to content

Commit 538cd2e

Browse files
committed
[Attributor] Multi-range accesses can be exact
Even if we have multiple access ranges, the access can be exact. It is not a MUST access but that is taken care of elsewhere. The tests were wrong as they contained uninitialized memory. When the memory is initialized it works as expected.
1 parent 129faec commit 538cd2e

File tree

2 files changed

+56
-32
lines changed

2 files changed

+56
-32
lines changed

llvm/lib/Transforms/IPO/AttributorAttributes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,7 @@ struct AA::PointerInfo::State : public AbstractState {
832832
bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
833833
for (auto Index : It.getSecond()) {
834834
auto &Access = AccessList[Index];
835-
if (!CB(Access, IsExact && Access.hasUniqueRange()))
835+
if (!CB(Access, IsExact))
836836
return false;
837837
}
838838
}

llvm/test/Transforms/Attributor/multiple-offsets-pointer-info.ll

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44

55
%struct.T = type { i32, [10 x [20 x i8]] }
66

7+
declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc"
8+
79
define i8 @select_offsets_simplifiable_1(i1 %cnd1, i1 %cnd2) {
8-
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
910
; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_1
10-
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR0:[0-9]+]] {
11+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {
1112
; CHECK-NEXT: entry:
12-
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
13+
; CHECK-NEXT: [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)
1314
; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
1415
; CHECK-NEXT: store i8 23, ptr [[GEP23]], align 4
1516
; CHECK-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 29
@@ -24,7 +25,7 @@ define i8 @select_offsets_simplifiable_1(i1 %cnd1, i1 %cnd2) {
2425
; CHECK-NEXT: ret i8 [[I]]
2526
;
2627
entry:
27-
%Bytes = alloca [1024 x i8], align 16
28+
%Bytes = call ptr @calloc(i64 1024, i64 1)
2829

2930
%gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
3031
store i8 23, ptr %gep23, align 4
@@ -47,7 +48,7 @@ entry:
4748
define i8 @select_offsets_simplifiable_2(i1 %cnd1, i1 %cnd2) {
4849
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
4950
; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_2
50-
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR0]] {
51+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1:[0-9]+]] {
5152
; CHECK-NEXT: entry:
5253
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
5354
; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
@@ -90,7 +91,7 @@ entry:
9091
define i8 @select_offsets_simplifiable_3(i1 %cnd1, i1 %cnd2) {
9192
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
9293
; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_3
93-
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR0]] {
94+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
9495
; CHECK-NEXT: entry:
9596
; CHECK-NEXT: [[BUNDLE:%.*]] = alloca [[STRUCT_T:%.*]], align 64
9697
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND1]], i64 1, i64 3
@@ -110,10 +111,33 @@ entry:
110111
ret i8 %i
111112
}
112113

114+
; Similar to select_offsets_not_simplifiable_3 but with uninitialized memory.
115+
define i8 @select_offsets_simplifiable_4(i1 %cnd1, i1 %cnd2) {
116+
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
117+
; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_4
118+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
119+
; CHECK-NEXT: entry:
120+
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
121+
; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
122+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
123+
; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
124+
; CHECK-NEXT: ret i8 100
125+
;
126+
entry:
127+
%Bytes = alloca [1024 x i8], align 16
128+
%sel0 = select i1 %cnd1, i64 23, i64 29
129+
%sel1 = select i1 %cnd2, i64 %sel0, i64 7
130+
%gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1
131+
store i8 100, ptr %gep.sel, align 4
132+
%gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 29
133+
%i = load i8, ptr %gep29, align 4
134+
ret i8 %i
135+
}
136+
113137
define i8 @select_offsets_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
114138
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
115139
; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_1
116-
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR0]] {
140+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
117141
; CHECK-NEXT: entry:
118142
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
119143
; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
@@ -138,7 +162,7 @@ entry:
138162
define i8 @select_offsets_not_simplifiable_2(i1 %cnd1, i1 %cnd2) {
139163
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
140164
; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_2
141-
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR0]] {
165+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
142166
; CHECK-NEXT: entry:
143167
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
144168
; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
@@ -163,11 +187,10 @@ entry:
163187
}
164188

165189
define i8 @select_offsets_not_simplifiable_3(i1 %cnd1, i1 %cnd2) {
166-
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
167190
; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_3
168-
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR0]] {
191+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {
169192
; CHECK-NEXT: entry:
170-
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
193+
; CHECK-NEXT: [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)
171194
; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
172195
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
173196
; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
@@ -177,7 +200,7 @@ define i8 @select_offsets_not_simplifiable_3(i1 %cnd1, i1 %cnd2) {
177200
; CHECK-NEXT: ret i8 [[I]]
178201
;
179202
entry:
180-
%Bytes = alloca [1024 x i8], align 16
203+
%Bytes = call ptr @calloc(i64 1024, i64 1)
181204
%sel0 = select i1 %cnd1, i64 23, i64 29
182205
%sel1 = select i1 %cnd2, i64 %sel0, i64 7
183206
%gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1
@@ -188,22 +211,21 @@ entry:
188211
}
189212

190213
define i8 @select_offsets_not_simplifiable_4(i1 %cnd1, i1 %cnd2) {
191-
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
192214
; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_4
193-
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR0]] {
215+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {
194216
; CHECK-NEXT: entry:
195-
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
217+
; CHECK-NEXT: [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)
196218
; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
197219
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
198220
; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
199221
; CHECK-NEXT: [[GEP_PLUS:%.*]] = getelementptr inbounds i8, ptr [[GEP_SEL]], i64 3
200222
; CHECK-NEXT: store i8 100, ptr [[GEP_PLUS]], align 4
201223
; CHECK-NEXT: [[GEP32:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 32
202-
; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP32]], align 16
224+
; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP32]], align 4
203225
; CHECK-NEXT: ret i8 [[I]]
204226
;
205227
entry:
206-
%Bytes = alloca [1024 x i8], align 16
228+
%Bytes = call ptr @calloc(i64 1024, i64 1)
207229
%sel0 = select i1 %cnd1, i64 23, i64 29
208230
%sel1 = select i1 %cnd2, i64 %sel0, i64 7
209231
%gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1
@@ -217,7 +239,7 @@ entry:
217239
define i8 @select_offsets_not_simplifiable_5(i1 %cnd1, i1 %cnd2) {
218240
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
219241
; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_5
220-
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR0]] {
242+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
221243
; CHECK-NEXT: entry:
222244
; CHECK-NEXT: [[BUNDLE:%.*]] = alloca [[STRUCT_T:%.*]], align 64
223245
; CHECK-NEXT: [[GEP_FIXED:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE]], i64 0, i32 1, i64 3, i64 5
@@ -247,7 +269,7 @@ entry:
247269
define i8 @select_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) {
248270
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
249271
; CHECK-LABEL: define {{[^@]+}}@select_gep_simplifiable_1
250-
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1:[0-9]+]] {
272+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2:[0-9]+]] {
251273
; CHECK-NEXT: entry:
252274
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
253275
; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7
@@ -271,10 +293,11 @@ entry:
271293
define i8 @select_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
272294
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn
273295
; CHECK-LABEL: define {{[^@]+}}@select_gep_not_simplifiable_1
274-
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2:[0-9]+]] {
296+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3:[0-9]+]] {
275297
; CHECK-NEXT: entry:
276298
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
277299
; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7
300+
; CHECK-NEXT: store i8 1, ptr [[GEP7]], align 4
278301
; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
279302
; CHECK-NEXT: [[SEL_PTR:%.*]] = select i1 [[CND1]], ptr [[GEP7]], ptr [[GEP23]]
280303
; CHECK-NEXT: store i8 42, ptr [[SEL_PTR]], align 4
@@ -284,6 +307,7 @@ define i8 @select_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
284307
entry:
285308
%Bytes = alloca [1024 x i8], align 16
286309
%gep7 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 7
310+
store i8 1, ptr %gep7, align 4
287311
%gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
288312
%sel.ptr = select i1 %cnd1, ptr %gep7, ptr %gep23
289313
store i8 42, ptr %sel.ptr, align 4
@@ -296,7 +320,7 @@ entry:
296320
define i8 @phi_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) {
297321
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn
298322
; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_1
299-
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] {
323+
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3]] {
300324
; CHECK-NEXT: entry:
301325
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
302326
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
@@ -342,7 +366,7 @@ join:
342366
define i8 @phi_gep_simplifiable_2(i1 %cnd1, i1 %cnd2) {
343367
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
344368
; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_2
345-
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
369+
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] {
346370
; CHECK-NEXT: entry:
347371
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
348372
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
@@ -383,7 +407,7 @@ join:
383407
define i8 @phi_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
384408
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn
385409
; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_1
386-
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] {
410+
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3]] {
387411
; CHECK-NEXT: entry:
388412
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
389413
; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
@@ -420,11 +444,10 @@ join:
420444
}
421445

422446
define i8 @phi_gep_not_simplifiable_2(i1 %cnd1, i1 %cnd2) {
423-
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn
424447
; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_2
425-
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] {
448+
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {
426449
; CHECK-NEXT: entry:
427-
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
450+
; CHECK-NEXT: [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)
428451
; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
429452
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
430453
; CHECK: then:
@@ -439,7 +462,7 @@ define i8 @phi_gep_not_simplifiable_2(i1 %cnd1, i1 %cnd2) {
439462
; CHECK-NEXT: ret i8 [[I]]
440463
;
441464
entry:
442-
%Bytes = alloca [1024 x i8], align 16
465+
%Bytes = call ptr @calloc(i64 1024, i64 1)
443466
%gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
444467
br i1 %cnd1, label %then, label %else
445468

@@ -460,7 +483,7 @@ join:
460483
define i8 @phi_offsets(i1 %cnd1, i1 %cnd2) {
461484
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none)
462485
; CHECK-LABEL: define {{[^@]+}}@phi_offsets
463-
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR0]] {
486+
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
464487
; CHECK-NEXT: entry:
465488
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
466489
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
@@ -493,9 +516,10 @@ join:
493516
}
494517

495518
;.
496-
; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(none) }
497-
; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(write) }
498-
; CHECK: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn }
519+
; CHECK: attributes #[[ATTR0:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" }
520+
; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(none) }
521+
; CHECK: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(write) }
522+
; CHECK: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn }
499523
;.
500524
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
501525
; CGSCC: {{.*}}

0 commit comments

Comments
 (0)