1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 @GInt1 = internal global i32 undef, align 4
6 @GInt2 = internal global i32 zeroinitializer, align 4
7 @GInt3 = internal global i32 undef, align 4
8 @GInt4 = internal global i32 zeroinitializer, align 4
9 @GInt5 = internal global i32 undef, align 4
11 declare void @llvm.assume(i1)
12 declare void @useI32(i32) nosync nocallback
13 declare void @free(ptr) allockind("free") "alloc-family"="malloc"
14 declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0, 1) "alloc-family"="malloc"
17 ; CHECK: @GInt1 = internal global i32 undef, align 4
18 ; CHECK: @GInt2 = internal global i32 0, align 4
19 ; CHECK: @GInt3 = internal global i32 undef, align 4
20 ; CHECK: @GInt4 = internal global i32 0, align 4
21 ; CHECK: @GInt5 = internal global i32 undef, align 4
22 ; CHECK: @B = global i32 0
24 define internal void @write1ToGInt1() {
25 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
26 ; CHECK-LABEL: define {{[^@]+}}@write1ToGInt1
27 ; CHECK-SAME: () #[[ATTR4:[0-9]+]] {
28 ; CHECK-NEXT: store i32 1, ptr @GInt1, align 4
29 ; CHECK-NEXT: ret void
31 store i32 1, ptr @GInt1
35 define internal void @write1ToGInt2() {
36 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
37 ; CHECK-LABEL: define {{[^@]+}}@write1ToGInt2
38 ; CHECK-SAME: () #[[ATTR4]] {
39 ; CHECK-NEXT: store i32 1, ptr @GInt2, align 4
40 ; CHECK-NEXT: ret void
42 store i32 1, ptr @GInt2
46 define void @entry1(i1 %c, i32 %v) {
47 ; TUNIT: Function Attrs: norecurse nosync
48 ; TUNIT-LABEL: define {{[^@]+}}@entry1
49 ; TUNIT-SAME: (i1 [[C:%.*]], i32 [[V:%.*]]) #[[ATTR5:[0-9]+]] {
50 ; TUNIT-NEXT: [[L0:%.*]] = load i32, ptr @GInt1, align 4
51 ; TUNIT-NEXT: call void @useI32(i32 [[L0]])
52 ; TUNIT-NEXT: call void @write1ToGInt1() #[[ATTR12:[0-9]+]]
53 ; TUNIT-NEXT: [[L1:%.*]] = load i32, ptr @GInt1, align 4
54 ; TUNIT-NEXT: call void @useI32(i32 [[L1]])
55 ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
57 ; TUNIT-NEXT: store i32 [[V]], ptr @GInt1, align 4
58 ; TUNIT-NEXT: [[L2:%.*]] = load i32, ptr @GInt1, align 4
59 ; TUNIT-NEXT: call void @useI32(i32 [[L2]])
60 ; TUNIT-NEXT: br label [[F]]
62 ; TUNIT-NEXT: [[L3:%.*]] = load i32, ptr @GInt1, align 4
63 ; TUNIT-NEXT: call void @useI32(i32 [[L3]])
64 ; TUNIT-NEXT: call void @write1ToGInt1() #[[ATTR12]]
65 ; TUNIT-NEXT: [[L4:%.*]] = load i32, ptr @GInt1, align 4
66 ; TUNIT-NEXT: call void @useI32(i32 [[L4]])
67 ; TUNIT-NEXT: ret void
69 ; CGSCC: Function Attrs: nosync
70 ; CGSCC-LABEL: define {{[^@]+}}@entry1
71 ; CGSCC-SAME: (i1 [[C:%.*]], i32 [[V:%.*]]) #[[ATTR5:[0-9]+]] {
72 ; CGSCC-NEXT: [[L0:%.*]] = load i32, ptr @GInt1, align 4
73 ; CGSCC-NEXT: call void @useI32(i32 [[L0]])
74 ; CGSCC-NEXT: call void @write1ToGInt1() #[[ATTR13:[0-9]+]]
75 ; CGSCC-NEXT: [[L1:%.*]] = load i32, ptr @GInt1, align 4
76 ; CGSCC-NEXT: call void @useI32(i32 [[L1]])
77 ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
79 ; CGSCC-NEXT: store i32 [[V]], ptr @GInt1, align 4
80 ; CGSCC-NEXT: [[L2:%.*]] = load i32, ptr @GInt1, align 4
81 ; CGSCC-NEXT: call void @useI32(i32 [[L2]])
82 ; CGSCC-NEXT: br label [[F]]
84 ; CGSCC-NEXT: [[L3:%.*]] = load i32, ptr @GInt1, align 4
85 ; CGSCC-NEXT: call void @useI32(i32 [[L3]])
86 ; CGSCC-NEXT: call void @write1ToGInt1() #[[ATTR13]]
87 ; CGSCC-NEXT: [[L4:%.*]] = load i32, ptr @GInt1, align 4
88 ; CGSCC-NEXT: call void @useI32(i32 [[L4]])
89 ; CGSCC-NEXT: ret void
91 %l0 = load i32, ptr @GInt1
92 call void @useI32(i32 %l0)
93 call void @write1ToGInt1();
94 %l1 = load i32, ptr @GInt1
95 call void @useI32(i32 %l1)
96 br i1 %c, label %T, label %F
98 store i32 %v, ptr @GInt1
99 %l2 = load i32, ptr @GInt1
100 call void @useI32(i32 %l2)
103 %l3 = load i32, ptr @GInt1
104 call void @useI32(i32 %l3)
105 call void @write1ToGInt1();
106 %l4 = load i32, ptr @GInt1
107 call void @useI32(i32 %l4)
111 define void @entry2(i1 %c, i32 %v) {
112 ; TUNIT: Function Attrs: norecurse nosync
113 ; TUNIT-LABEL: define {{[^@]+}}@entry2
114 ; TUNIT-SAME: (i1 [[C:%.*]], i32 [[V:%.*]]) #[[ATTR5]] {
115 ; TUNIT-NEXT: [[L0:%.*]] = load i32, ptr @GInt2, align 4
116 ; TUNIT-NEXT: call void @useI32(i32 [[L0]])
117 ; TUNIT-NEXT: call void @write1ToGInt2() #[[ATTR12]]
118 ; TUNIT-NEXT: [[L1:%.*]] = load i32, ptr @GInt2, align 4
119 ; TUNIT-NEXT: call void @useI32(i32 [[L1]])
120 ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
122 ; TUNIT-NEXT: store i32 [[V]], ptr @GInt2, align 4
123 ; TUNIT-NEXT: [[L2:%.*]] = load i32, ptr @GInt2, align 4
124 ; TUNIT-NEXT: call void @useI32(i32 [[L2]])
125 ; TUNIT-NEXT: br label [[F]]
127 ; TUNIT-NEXT: [[L3:%.*]] = load i32, ptr @GInt2, align 4
128 ; TUNIT-NEXT: call void @useI32(i32 [[L3]])
129 ; TUNIT-NEXT: call void @write1ToGInt2() #[[ATTR12]]
130 ; TUNIT-NEXT: [[L4:%.*]] = load i32, ptr @GInt2, align 4
131 ; TUNIT-NEXT: call void @useI32(i32 [[L4]])
132 ; TUNIT-NEXT: ret void
134 ; CGSCC: Function Attrs: nosync
135 ; CGSCC-LABEL: define {{[^@]+}}@entry2
136 ; CGSCC-SAME: (i1 [[C:%.*]], i32 [[V:%.*]]) #[[ATTR5]] {
137 ; CGSCC-NEXT: [[L0:%.*]] = load i32, ptr @GInt2, align 4
138 ; CGSCC-NEXT: call void @useI32(i32 [[L0]])
139 ; CGSCC-NEXT: call void @write1ToGInt2() #[[ATTR13]]
140 ; CGSCC-NEXT: [[L1:%.*]] = load i32, ptr @GInt2, align 4
141 ; CGSCC-NEXT: call void @useI32(i32 [[L1]])
142 ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
144 ; CGSCC-NEXT: store i32 [[V]], ptr @GInt2, align 4
145 ; CGSCC-NEXT: [[L2:%.*]] = load i32, ptr @GInt2, align 4
146 ; CGSCC-NEXT: call void @useI32(i32 [[L2]])
147 ; CGSCC-NEXT: br label [[F]]
149 ; CGSCC-NEXT: [[L3:%.*]] = load i32, ptr @GInt2, align 4
150 ; CGSCC-NEXT: call void @useI32(i32 [[L3]])
151 ; CGSCC-NEXT: call void @write1ToGInt2() #[[ATTR13]]
152 ; CGSCC-NEXT: [[L4:%.*]] = load i32, ptr @GInt2, align 4
153 ; CGSCC-NEXT: call void @useI32(i32 [[L4]])
154 ; CGSCC-NEXT: ret void
156 %l0 = load i32, ptr @GInt2
157 call void @useI32(i32 %l0)
158 call void @write1ToGInt2();
159 %l1 = load i32, ptr @GInt2
160 call void @useI32(i32 %l1)
161 br i1 %c, label %T, label %F
163 store i32 %v, ptr @GInt2
164 %l2 = load i32, ptr @GInt2
165 call void @useI32(i32 %l2)
168 %l3 = load i32, ptr @GInt2
169 call void @useI32(i32 %l3)
170 call void @write1ToGInt2();
171 %l4 = load i32, ptr @GInt2
172 call void @useI32(i32 %l4)
175 define void @entry3(i1 %c, i32 %v) {
176 ; TUNIT: Function Attrs: norecurse nosync
177 ; TUNIT-LABEL: define {{[^@]+}}@entry3
178 ; TUNIT-SAME: (i1 [[C:%.*]], i32 [[V:%.*]]) #[[ATTR5]] {
179 ; TUNIT-NEXT: call void @useI32(i32 1)
180 ; TUNIT-NEXT: store i32 1, ptr @GInt3, align 4
181 ; TUNIT-NEXT: call void @useI32(i32 noundef 1)
182 ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
184 ; TUNIT-NEXT: store i32 [[V]], ptr @GInt3, align 4
185 ; TUNIT-NEXT: [[L2:%.*]] = load i32, ptr @GInt3, align 4
186 ; TUNIT-NEXT: call void @useI32(i32 [[L2]])
187 ; TUNIT-NEXT: br label [[F]]
189 ; TUNIT-NEXT: [[L3:%.*]] = load i32, ptr @GInt3, align 4
190 ; TUNIT-NEXT: call void @useI32(i32 [[L3]])
191 ; TUNIT-NEXT: store i32 1, ptr @GInt3, align 4
192 ; TUNIT-NEXT: call void @useI32(i32 noundef 1)
193 ; TUNIT-NEXT: ret void
195 ; CGSCC: Function Attrs: norecurse nosync
196 ; CGSCC-LABEL: define {{[^@]+}}@entry3
197 ; CGSCC-SAME: (i1 [[C:%.*]], i32 [[V:%.*]]) #[[ATTR6:[0-9]+]] {
198 ; CGSCC-NEXT: call void @useI32(i32 1)
199 ; CGSCC-NEXT: store i32 1, ptr @GInt3, align 4
200 ; CGSCC-NEXT: call void @useI32(i32 noundef 1)
201 ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
203 ; CGSCC-NEXT: store i32 [[V]], ptr @GInt3, align 4
204 ; CGSCC-NEXT: [[L2:%.*]] = load i32, ptr @GInt3, align 4
205 ; CGSCC-NEXT: call void @useI32(i32 [[L2]])
206 ; CGSCC-NEXT: br label [[F]]
208 ; CGSCC-NEXT: [[L3:%.*]] = load i32, ptr @GInt3, align 4
209 ; CGSCC-NEXT: call void @useI32(i32 [[L3]])
210 ; CGSCC-NEXT: store i32 1, ptr @GInt3, align 4
211 ; CGSCC-NEXT: call void @useI32(i32 noundef 1)
212 ; CGSCC-NEXT: ret void
214 %l0 = load i32, ptr @GInt3
215 call void @useI32(i32 %l0)
216 store i32 1, ptr @GInt3
217 %l1 = load i32, ptr @GInt3
218 call void @useI32(i32 %l1)
219 br i1 %c, label %T, label %F
221 store i32 %v, ptr @GInt3
222 %l2 = load i32, ptr @GInt3
223 call void @useI32(i32 %l2)
226 %l3 = load i32, ptr @GInt3
227 call void @useI32(i32 %l3)
228 store i32 1, ptr @GInt3
229 %l4 = load i32, ptr @GInt3
230 call void @useI32(i32 %l4)
234 define void @entry4(i1 %c, i32 %v) {
235 ; TUNIT: Function Attrs: norecurse nosync
236 ; TUNIT-LABEL: define {{[^@]+}}@entry4
237 ; TUNIT-SAME: (i1 [[C:%.*]], i32 [[V:%.*]]) #[[ATTR5]] {
238 ; TUNIT-NEXT: [[L0:%.*]] = load i32, ptr @GInt4, align 4
239 ; TUNIT-NEXT: call void @useI32(i32 noundef [[L0]])
240 ; TUNIT-NEXT: store i32 1, ptr @GInt4, align 4
241 ; TUNIT-NEXT: call void @useI32(i32 noundef 1)
242 ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
244 ; TUNIT-NEXT: store i32 [[V]], ptr @GInt4, align 4
245 ; TUNIT-NEXT: [[L2:%.*]] = load i32, ptr @GInt4, align 4
246 ; TUNIT-NEXT: call void @useI32(i32 [[L2]])
247 ; TUNIT-NEXT: br label [[F]]
249 ; TUNIT-NEXT: [[L3:%.*]] = load i32, ptr @GInt4, align 4
250 ; TUNIT-NEXT: call void @useI32(i32 [[L3]])
251 ; TUNIT-NEXT: store i32 1, ptr @GInt4, align 4
252 ; TUNIT-NEXT: call void @useI32(i32 noundef 1)
253 ; TUNIT-NEXT: ret void
255 ; CGSCC: Function Attrs: norecurse nosync
256 ; CGSCC-LABEL: define {{[^@]+}}@entry4
257 ; CGSCC-SAME: (i1 [[C:%.*]], i32 [[V:%.*]]) #[[ATTR6]] {
258 ; CGSCC-NEXT: [[L0:%.*]] = load i32, ptr @GInt4, align 4
259 ; CGSCC-NEXT: call void @useI32(i32 noundef [[L0]])
260 ; CGSCC-NEXT: store i32 1, ptr @GInt4, align 4
261 ; CGSCC-NEXT: call void @useI32(i32 noundef 1)
262 ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
264 ; CGSCC-NEXT: store i32 [[V]], ptr @GInt4, align 4
265 ; CGSCC-NEXT: [[L2:%.*]] = load i32, ptr @GInt4, align 4
266 ; CGSCC-NEXT: call void @useI32(i32 [[L2]])
267 ; CGSCC-NEXT: br label [[F]]
269 ; CGSCC-NEXT: [[L3:%.*]] = load i32, ptr @GInt4, align 4
270 ; CGSCC-NEXT: call void @useI32(i32 [[L3]])
271 ; CGSCC-NEXT: store i32 1, ptr @GInt4, align 4
272 ; CGSCC-NEXT: call void @useI32(i32 noundef 1)
273 ; CGSCC-NEXT: ret void
275 %l0 = load i32, ptr @GInt4
276 call void @useI32(i32 %l0)
277 store i32 1, ptr @GInt4
278 %l1 = load i32, ptr @GInt4
279 call void @useI32(i32 %l1)
280 br i1 %c, label %T, label %F
282 store i32 %v, ptr @GInt4
283 %l2 = load i32, ptr @GInt4
284 call void @useI32(i32 %l2)
287 %l3 = load i32, ptr @GInt4
288 call void @useI32(i32 %l3)
289 store i32 1, ptr @GInt4
290 %l4 = load i32, ptr @GInt4
291 call void @useI32(i32 %l4)
295 ; TODO: In this test we can replace %l0, in the others above we cannot.
296 define void @entry5(i1 %c, i32 %v) {
297 ; TUNIT: Function Attrs: norecurse nosync
298 ; TUNIT-LABEL: define {{[^@]+}}@entry5
299 ; TUNIT-SAME: (i1 [[C:%.*]], i32 [[V:%.*]]) #[[ATTR5]] {
300 ; TUNIT-NEXT: call void @useI32(i32 1)
301 ; TUNIT-NEXT: store i32 1, ptr @GInt5, align 4
302 ; TUNIT-NEXT: call void @useI32(i32 noundef 1) #[[ATTR6:[0-9]+]]
303 ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
305 ; TUNIT-NEXT: store i32 [[V]], ptr @GInt5, align 4
306 ; TUNIT-NEXT: [[L2:%.*]] = load i32, ptr @GInt5, align 4
307 ; TUNIT-NEXT: call void @useI32(i32 [[L2]]) #[[ATTR6]]
308 ; TUNIT-NEXT: br label [[F]]
310 ; TUNIT-NEXT: [[L3:%.*]] = load i32, ptr @GInt5, align 4
311 ; TUNIT-NEXT: call void @useI32(i32 [[L3]]) #[[ATTR6]]
312 ; TUNIT-NEXT: store i32 1, ptr @GInt5, align 4
313 ; TUNIT-NEXT: call void @useI32(i32 noundef 1) #[[ATTR6]]
314 ; TUNIT-NEXT: ret void
316 ; CGSCC: Function Attrs: norecurse nosync
317 ; CGSCC-LABEL: define {{[^@]+}}@entry5
318 ; CGSCC-SAME: (i1 [[C:%.*]], i32 [[V:%.*]]) #[[ATTR6]] {
319 ; CGSCC-NEXT: call void @useI32(i32 1)
320 ; CGSCC-NEXT: store i32 1, ptr @GInt5, align 4
321 ; CGSCC-NEXT: call void @useI32(i32 noundef 1) #[[ATTR7:[0-9]+]]
322 ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
324 ; CGSCC-NEXT: store i32 [[V]], ptr @GInt5, align 4
325 ; CGSCC-NEXT: [[L2:%.*]] = load i32, ptr @GInt5, align 4
326 ; CGSCC-NEXT: call void @useI32(i32 [[L2]]) #[[ATTR7]]
327 ; CGSCC-NEXT: br label [[F]]
329 ; CGSCC-NEXT: [[L3:%.*]] = load i32, ptr @GInt5, align 4
330 ; CGSCC-NEXT: call void @useI32(i32 [[L3]]) #[[ATTR7]]
331 ; CGSCC-NEXT: store i32 1, ptr @GInt5, align 4
332 ; CGSCC-NEXT: call void @useI32(i32 noundef 1) #[[ATTR7]]
333 ; CGSCC-NEXT: ret void
335 %l0 = load i32, ptr @GInt5
336 call void @useI32(i32 %l0)
337 store i32 1, ptr @GInt5
338 %l1 = load i32, ptr @GInt5
339 call void @useI32(i32 %l1) nocallback
340 br i1 %c, label %T, label %F
342 store i32 %v, ptr @GInt5
343 %l2 = load i32, ptr @GInt5
344 call void @useI32(i32 %l2) nocallback
347 %l3 = load i32, ptr @GInt5
348 call void @useI32(i32 %l3) nocallback
349 store i32 1, ptr @GInt5
350 %l4 = load i32, ptr @GInt5
351 call void @useI32(i32 %l4) nocallback
356 declare void @use_4_i8(i8, i8, i8, i8) nocallback
358 define void @exclusion_set1(i1 %c1, i1 %c2, i1 %c3) {
359 ; CHECK-LABEL: define {{[^@]+}}@exclusion_set1
360 ; CHECK-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) {
362 ; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1
363 ; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[CALL_H2S]], i8 0, i64 4, i1 false)
364 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[CALL_H2S]], i64 1
365 ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[CALL_H2S]], i64 2
366 ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds i8, ptr [[CALL_H2S]], i64 3
367 ; CHECK-NEXT: [[L0_A:%.*]] = load i8, ptr [[CALL_H2S]], align 1
368 ; CHECK-NEXT: [[L1_A:%.*]] = load i8, ptr [[GEP1]], align 1
369 ; CHECK-NEXT: [[L2_A:%.*]] = load i8, ptr [[GEP2]], align 1
370 ; CHECK-NEXT: [[L3_A:%.*]] = load i8, ptr [[GEP3]], align 1
371 ; CHECK-NEXT: call void @use_4_i8(i8 noundef [[L0_A]], i8 noundef [[L1_A]], i8 noundef [[L2_A]], i8 noundef [[L3_A]])
372 ; CHECK-NEXT: store i8 1, ptr [[CALL_H2S]], align 4
373 ; CHECK-NEXT: [[L1_B:%.*]] = load i8, ptr [[GEP1]], align 1
374 ; CHECK-NEXT: [[L2_B:%.*]] = load i8, ptr [[GEP2]], align 1
375 ; CHECK-NEXT: [[L3_B:%.*]] = load i8, ptr [[GEP3]], align 1
376 ; CHECK-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef [[L1_B]], i8 noundef [[L2_B]], i8 noundef [[L3_B]])
377 ; CHECK-NEXT: br i1 [[C1]], label [[IF_MERGE1:%.*]], label [[IF_THEN:%.*]]
379 ; CHECK-NEXT: [[L1_C:%.*]] = load i8, ptr [[GEP1]], align 1
380 ; CHECK-NEXT: [[L2_C:%.*]] = load i8, ptr [[GEP2]], align 1
381 ; CHECK-NEXT: [[L3_C:%.*]] = load i8, ptr [[GEP3]], align 1
382 ; CHECK-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef [[L1_C]], i8 noundef [[L2_C]], i8 noundef [[L3_C]])
383 ; CHECK-NEXT: store i8 2, ptr [[GEP1]], align 4
384 ; CHECK-NEXT: [[L2_D:%.*]] = load i8, ptr [[GEP2]], align 1
385 ; CHECK-NEXT: [[L3_D:%.*]] = load i8, ptr [[GEP3]], align 1
386 ; CHECK-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 noundef [[L2_D]], i8 noundef [[L3_D]])
387 ; CHECK-NEXT: br i1 [[C1]], label [[IF_MERGE1]], label [[IF_THEN2:%.*]]
389 ; CHECK-NEXT: [[L2_E:%.*]] = load i8, ptr [[GEP2]], align 1
390 ; CHECK-NEXT: [[L3_E:%.*]] = load i8, ptr [[GEP3]], align 1
391 ; CHECK-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 noundef [[L2_E]], i8 noundef [[L3_E]])
392 ; CHECK-NEXT: store i8 3, ptr [[GEP2]], align 4
393 ; CHECK-NEXT: [[L3_F:%.*]] = load i8, ptr [[GEP3]], align 1
394 ; CHECK-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 noundef 3, i8 noundef [[L3_F]])
395 ; CHECK-NEXT: br i1 [[C2]], label [[IF_MERGE2:%.*]], label [[IF_THEN3:%.*]]
397 ; CHECK-NEXT: [[L1_G:%.*]] = load i8, ptr [[GEP1]], align 1
398 ; CHECK-NEXT: [[L2_G:%.*]] = load i8, ptr [[GEP2]], align 1
399 ; CHECK-NEXT: [[L3_G:%.*]] = load i8, ptr [[GEP3]], align 1
400 ; CHECK-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef [[L1_G]], i8 noundef [[L2_G]], i8 noundef [[L3_G]])
401 ; CHECK-NEXT: br label [[IF_MERGE2]]
403 ; CHECK-NEXT: [[L1_H:%.*]] = load i8, ptr [[GEP1]], align 1
404 ; CHECK-NEXT: [[L2_H:%.*]] = load i8, ptr [[GEP2]], align 1
405 ; CHECK-NEXT: [[L3_H:%.*]] = load i8, ptr [[GEP3]], align 1
406 ; CHECK-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef [[L1_H]], i8 noundef [[L2_H]], i8 noundef [[L3_H]])
407 ; CHECK-NEXT: br label [[IF_END:%.*]]
409 ; CHECK-NEXT: [[L3_I:%.*]] = load i8, ptr [[GEP3]], align 1
410 ; CHECK-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 noundef 3, i8 noundef [[L3_I]])
411 ; CHECK-NEXT: store i8 4, ptr [[GEP3]], align 4
412 ; CHECK-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 noundef 3, i8 noundef 4)
413 ; CHECK-NEXT: br label [[IF_END]]
415 ; CHECK-NEXT: [[L1_K:%.*]] = load i8, ptr [[GEP1]], align 1
416 ; CHECK-NEXT: [[L2_K:%.*]] = load i8, ptr [[GEP2]], align 1
417 ; CHECK-NEXT: [[L3_K:%.*]] = load i8, ptr [[GEP3]], align 1
418 ; CHECK-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef [[L1_K]], i8 noundef [[L2_K]], i8 noundef [[L3_K]])
419 ; CHECK-NEXT: ret void
422 %call = call noalias ptr @calloc(i64 1, i64 4) norecurse
423 %gep0 = getelementptr inbounds i8, ptr %call, i64 0
424 %gep1 = getelementptr inbounds i8, ptr %call, i64 1
425 %gep2 = getelementptr inbounds i8, ptr %call, i64 2
426 %gep3 = getelementptr inbounds i8, ptr %call, i64 3
428 %l0_a = load i8, ptr %gep0
429 %l1_a = load i8, ptr %gep1
430 %l2_a = load i8, ptr %gep2
431 %l3_a = load i8, ptr %gep3
432 call void @use_4_i8(i8 %l0_a, i8 %l1_a, i8 %l2_a, i8 %l3_a)
434 store i8 1, ptr %gep0, align 4
436 %l0_b = load i8, ptr %gep0
437 %l1_b = load i8, ptr %gep1
438 %l2_b = load i8, ptr %gep2
439 %l3_b = load i8, ptr %gep3
440 call void @use_4_i8(i8 %l0_b, i8 %l1_b, i8 %l2_b, i8 %l3_b)
442 br i1 %c1, label %if.merge1, label %if.then
445 %l0_c = load i8, ptr %gep0
446 %l1_c = load i8, ptr %gep1
447 %l2_c = load i8, ptr %gep2
448 %l3_c = load i8, ptr %gep3
449 call void @use_4_i8(i8 %l0_c, i8 %l1_c, i8 %l2_c, i8 %l3_c)
451 store i8 2, ptr %gep1, align 4
453 %l0_d = load i8, ptr %gep0
454 %l1_d = load i8, ptr %gep1
455 %l2_d = load i8, ptr %gep2
456 %l3_d = load i8, ptr %gep3
457 call void @use_4_i8(i8 %l0_d, i8 %l1_d, i8 %l2_d, i8 %l3_d)
459 br i1 %c1, label %if.merge1, label %if.then2
462 %l0_e = load i8, ptr %gep0
463 %l1_e = load i8, ptr %gep1
464 %l2_e = load i8, ptr %gep2
465 %l3_e = load i8, ptr %gep3
466 call void @use_4_i8(i8 %l0_e, i8 %l1_e, i8 %l2_e, i8 %l3_e)
468 store i8 3, ptr %gep2, align 4
470 %l0_f = load i8, ptr %gep0
471 %l1_f = load i8, ptr %gep1
472 %l2_f = load i8, ptr %gep2
473 %l3_f = load i8, ptr %gep3
474 call void @use_4_i8(i8 %l0_f, i8 %l1_f, i8 %l2_f, i8 %l3_f)
476 br i1 %c2, label %if.merge2, label %if.then3
480 %l0_g = load i8, ptr %gep0
481 %l1_g = load i8, ptr %gep1
482 %l2_g = load i8, ptr %gep2
483 %l3_g = load i8, ptr %gep3
484 call void @use_4_i8(i8 %l0_g, i8 %l1_g, i8 %l2_g, i8 %l3_g)
490 %l0_h = load i8, ptr %gep0
491 %l1_h = load i8, ptr %gep1
492 %l2_h = load i8, ptr %gep2
493 %l3_h = load i8, ptr %gep3
494 call void @use_4_i8(i8 %l0_h, i8 %l1_h, i8 %l2_h, i8 %l3_h)
500 %l0_i = load i8, ptr %gep0
501 %l1_i = load i8, ptr %gep1
502 %l2_i = load i8, ptr %gep2
503 %l3_i = load i8, ptr %gep3
504 call void @use_4_i8(i8 %l0_i, i8 %l1_i, i8 %l2_i, i8 %l3_i)
506 store i8 4, ptr %gep3, align 4
508 %l0_j = load i8, ptr %gep0
509 %l1_j = load i8, ptr %gep1
510 %l2_j = load i8, ptr %gep2
511 %l3_j = load i8, ptr %gep3
512 call void @use_4_i8(i8 %l0_j, i8 %l1_j, i8 %l2_j, i8 %l3_j)
517 %l0_k = load i8, ptr %gep0
518 %l1_k = load i8, ptr %gep1
519 %l2_k = load i8, ptr %gep2
520 %l3_k = load i8, ptr %gep3
521 call void @use_4_i8(i8 %l0_k, i8 %l1_k, i8 %l2_k, i8 %l3_k)
523 call void @free(ptr %call) norecurse
527 define void @exclusion_set2(i1 %c1, i1 %c2, i1 %c3) {
528 ; TUNIT: Function Attrs: norecurse
529 ; TUNIT-LABEL: define {{[^@]+}}@exclusion_set2
530 ; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR7:[0-9]+]] {
532 ; TUNIT-NEXT: call void @use_4_i8(i8 undef, i8 undef, i8 undef, i8 undef)
533 ; TUNIT-NEXT: call void @use_4_i8(i8 noundef 1, i8 undef, i8 undef, i8 undef)
534 ; TUNIT-NEXT: br i1 [[C1]], label [[IF_MERGE1:%.*]], label [[IF_THEN:%.*]]
536 ; TUNIT-NEXT: call void @use_4_i8(i8 noundef 1, i8 undef, i8 undef, i8 undef)
537 ; TUNIT-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 undef, i8 undef)
538 ; TUNIT-NEXT: br i1 [[C1]], label [[IF_MERGE1]], label [[IF_THEN2:%.*]]
540 ; TUNIT-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 undef, i8 undef)
541 ; TUNIT-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 noundef 3, i8 undef)
542 ; TUNIT-NEXT: br i1 [[C2]], label [[IF_MERGE2:%.*]], label [[IF_THEN3:%.*]]
544 ; TUNIT-NEXT: call void @use_4_i8(i8 noundef 1, i8 2, i8 undef, i8 undef)
545 ; TUNIT-NEXT: br label [[IF_MERGE2]]
547 ; TUNIT-NEXT: call void @use_4_i8(i8 noundef 1, i8 2, i8 3, i8 undef)
548 ; TUNIT-NEXT: br label [[IF_END:%.*]]
550 ; TUNIT-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 noundef 3, i8 undef)
551 ; TUNIT-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 noundef 3, i8 noundef 4)
552 ; TUNIT-NEXT: br label [[IF_END]]
554 ; TUNIT-NEXT: call void @use_4_i8(i8 noundef 1, i8 2, i8 3, i8 4)
555 ; TUNIT-NEXT: ret void
557 ; CGSCC: Function Attrs: norecurse
558 ; CGSCC-LABEL: define {{[^@]+}}@exclusion_set2
559 ; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR8:[0-9]+]] {
561 ; CGSCC-NEXT: call void @use_4_i8(i8 undef, i8 undef, i8 undef, i8 undef)
562 ; CGSCC-NEXT: call void @use_4_i8(i8 noundef 1, i8 undef, i8 undef, i8 undef)
563 ; CGSCC-NEXT: br i1 [[C1]], label [[IF_MERGE1:%.*]], label [[IF_THEN:%.*]]
565 ; CGSCC-NEXT: call void @use_4_i8(i8 noundef 1, i8 undef, i8 undef, i8 undef)
566 ; CGSCC-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 undef, i8 undef)
567 ; CGSCC-NEXT: br i1 [[C1]], label [[IF_MERGE1]], label [[IF_THEN2:%.*]]
569 ; CGSCC-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 undef, i8 undef)
570 ; CGSCC-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 noundef 3, i8 undef)
571 ; CGSCC-NEXT: br i1 [[C2]], label [[IF_MERGE2:%.*]], label [[IF_THEN3:%.*]]
573 ; CGSCC-NEXT: call void @use_4_i8(i8 noundef 1, i8 2, i8 undef, i8 undef)
574 ; CGSCC-NEXT: br label [[IF_MERGE2]]
576 ; CGSCC-NEXT: call void @use_4_i8(i8 noundef 1, i8 2, i8 3, i8 undef)
577 ; CGSCC-NEXT: br label [[IF_END:%.*]]
579 ; CGSCC-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 noundef 3, i8 undef)
580 ; CGSCC-NEXT: call void @use_4_i8(i8 noundef 1, i8 noundef 2, i8 noundef 3, i8 noundef 4)
581 ; CGSCC-NEXT: br label [[IF_END]]
583 ; CGSCC-NEXT: call void @use_4_i8(i8 noundef 1, i8 2, i8 3, i8 4)
584 ; CGSCC-NEXT: ret void
587 %alloc = alloca i8, i32 4
588 %gep0 = getelementptr inbounds i8, ptr %alloc, i64 0
589 %gep1 = getelementptr inbounds i8, ptr %alloc, i64 1
590 %gep2 = getelementptr inbounds i8, ptr %alloc, i64 2
591 %gep3 = getelementptr inbounds i8, ptr %alloc, i64 3
593 %l0_a = load i8, ptr %gep0
594 %l1_a = load i8, ptr %gep1
595 %l2_a = load i8, ptr %gep2
596 %l3_a = load i8, ptr %gep3
597 call void @use_4_i8(i8 %l0_a, i8 %l1_a, i8 %l2_a, i8 %l3_a)
599 store i8 1, ptr %gep0, align 4
601 %l0_b = load i8, ptr %gep0
602 %l1_b = load i8, ptr %gep1
603 %l2_b = load i8, ptr %gep2
604 %l3_b = load i8, ptr %gep3
605 call void @use_4_i8(i8 %l0_b, i8 %l1_b, i8 %l2_b, i8 %l3_b)
607 br i1 %c1, label %if.merge1, label %if.then
610 %l0_c = load i8, ptr %gep0
611 %l1_c = load i8, ptr %gep1
612 %l2_c = load i8, ptr %gep2
613 %l3_c = load i8, ptr %gep3
614 call void @use_4_i8(i8 %l0_c, i8 %l1_c, i8 %l2_c, i8 %l3_c)
616 store i8 2, ptr %gep1, align 4
618 %l0_d = load i8, ptr %gep0
619 %l1_d = load i8, ptr %gep1
620 %l2_d = load i8, ptr %gep2
621 %l3_d = load i8, ptr %gep3
622 call void @use_4_i8(i8 %l0_d, i8 %l1_d, i8 %l2_d, i8 %l3_d)
624 br i1 %c1, label %if.merge1, label %if.then2
627 %l0_e = load i8, ptr %gep0
628 %l1_e = load i8, ptr %gep1
629 %l2_e = load i8, ptr %gep2
630 %l3_e = load i8, ptr %gep3
631 call void @use_4_i8(i8 %l0_e, i8 %l1_e, i8 %l2_e, i8 %l3_e)
633 store i8 3, ptr %gep2, align 4
635 %l0_f = load i8, ptr %gep0
636 %l1_f = load i8, ptr %gep1
637 %l2_f = load i8, ptr %gep2
638 %l3_f = load i8, ptr %gep3
639 call void @use_4_i8(i8 %l0_f, i8 %l1_f, i8 %l2_f, i8 %l3_f)
641 br i1 %c2, label %if.merge2, label %if.then3
645 %l0_g = load i8, ptr %gep0
646 %l1_g = load i8, ptr %gep1
647 %l2_g = load i8, ptr %gep2
648 %l3_g = load i8, ptr %gep3
649 call void @use_4_i8(i8 %l0_g, i8 %l1_g, i8 %l2_g, i8 %l3_g)
655 %l0_h = load i8, ptr %gep0
656 %l1_h = load i8, ptr %gep1
657 %l2_h = load i8, ptr %gep2
658 %l3_h = load i8, ptr %gep3
659 call void @use_4_i8(i8 %l0_h, i8 %l1_h, i8 %l2_h, i8 %l3_h)
665 %l0_i = load i8, ptr %gep0
666 %l1_i = load i8, ptr %gep1
667 %l2_i = load i8, ptr %gep2
668 %l3_i = load i8, ptr %gep3
669 call void @use_4_i8(i8 %l0_i, i8 %l1_i, i8 %l2_i, i8 %l3_i)
671 store i8 4, ptr %gep3, align 4
673 %l0_j = load i8, ptr %gep0
674 %l1_j = load i8, ptr %gep1
675 %l2_j = load i8, ptr %gep2
676 %l3_j = load i8, ptr %gep3
677 call void @use_4_i8(i8 %l0_j, i8 %l1_j, i8 %l2_j, i8 %l3_j)
682 %l0_k = load i8, ptr %gep0
683 %l1_k = load i8, ptr %gep1
684 %l2_k = load i8, ptr %gep2
685 %l3_k = load i8, ptr %gep3
686 call void @use_4_i8(i8 %l0_k, i8 %l1_k, i8 %l2_k, i8 %l3_k)
691 declare void @usei32(i32) nocallback nosync
692 define internal void @exclusion_set3_helper(i1 %c, ptr %p) {
693 ; TUNIT: Function Attrs: nosync
694 ; TUNIT-LABEL: define {{[^@]+}}@exclusion_set3_helper
695 ; TUNIT-SAME: (i1 noundef [[C:%.*]], ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] {
696 ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
698 ; TUNIT-NEXT: store i32 42, ptr [[P]], align 4
699 ; TUNIT-NEXT: br label [[M:%.*]]
701 ; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 4
702 ; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[L]], 1
703 ; TUNIT-NEXT: store i32 [[ADD]], ptr [[P]], align 4
704 ; TUNIT-NEXT: [[CND:%.*]] = icmp eq i32 [[L]], 100
705 ; TUNIT-NEXT: br i1 [[CND]], label [[F2:%.*]], label [[F]]
707 ; TUNIT-NEXT: [[USE1:%.*]] = load i32, ptr [[P]], align 4
708 ; TUNIT-NEXT: call void @usei32(i32 [[USE1]])
709 ; TUNIT-NEXT: store i32 77, ptr [[P]], align 4
710 ; TUNIT-NEXT: call void @exclusion_set3_helper(i1 noundef true, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[P]]) #[[ATTR8]]
711 ; TUNIT-NEXT: [[USE2:%.*]] = load i32, ptr [[P]], align 4
712 ; TUNIT-NEXT: call void @usei32(i32 noundef [[USE2]])
713 ; TUNIT-NEXT: br label [[T]]
715 ; TUNIT-NEXT: call void @usei32(i32 noundef 42)
716 ; TUNIT-NEXT: ret void
718 ; CGSCC: Function Attrs: nosync
719 ; CGSCC-LABEL: define {{[^@]+}}@exclusion_set3_helper
720 ; CGSCC-SAME: (i1 noundef [[C:%.*]], ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR5]] {
721 ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
723 ; CGSCC-NEXT: store i32 42, ptr [[P]], align 4
724 ; CGSCC-NEXT: br label [[M:%.*]]
726 ; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 4
727 ; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[L]], 1
728 ; CGSCC-NEXT: store i32 [[ADD]], ptr [[P]], align 4
729 ; CGSCC-NEXT: [[CND:%.*]] = icmp eq i32 [[L]], 100
730 ; CGSCC-NEXT: br i1 [[CND]], label [[F2:%.*]], label [[F]]
732 ; CGSCC-NEXT: [[USE1:%.*]] = load i32, ptr [[P]], align 4
733 ; CGSCC-NEXT: call void @usei32(i32 [[USE1]])
734 ; CGSCC-NEXT: store i32 77, ptr [[P]], align 4
735 ; CGSCC-NEXT: call void @exclusion_set3_helper(i1 noundef true, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[P]]) #[[ATTR5]]
736 ; CGSCC-NEXT: [[USE2:%.*]] = load i32, ptr [[P]], align 4
737 ; CGSCC-NEXT: call void @usei32(i32 [[USE2]])
738 ; CGSCC-NEXT: br label [[T]]
740 ; CGSCC-NEXT: [[USE3:%.*]] = load i32, ptr [[P]], align 4
741 ; CGSCC-NEXT: call void @usei32(i32 [[USE3]])
742 ; CGSCC-NEXT: ret void
744 br i1 %c, label %t, label %f
749 %l = load i32, ptr %p
751 store i32 %add, ptr %p
752 %cnd = icmp eq i32 %l, 100
753 br i1 %cnd, label %f2, label %f
755 %use1 = load i32, ptr %p
756 call void @usei32(i32 %use1)
758 call void @exclusion_set3_helper(i1 true, ptr %p)
759 %use2 = load i32, ptr %p
760 call void @usei32(i32 %use2)
763 %use3 = load i32, ptr %p
764 call void @usei32(i32 %use3)
768 define i32 @exclusion_set3(i1 %c) {
769 ; TUNIT: Function Attrs: norecurse nosync
770 ; TUNIT-LABEL: define {{[^@]+}}@exclusion_set3
771 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR5]] {
772 ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
773 ; TUNIT-NEXT: store i32 3, ptr [[A]], align 4
774 ; TUNIT-NEXT: call void @exclusion_set3_helper(i1 noundef [[C]], ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]]) #[[ATTR8]]
775 ; TUNIT-NEXT: [[FINAL:%.*]] = load i32, ptr [[A]], align 4
776 ; TUNIT-NEXT: ret i32 [[FINAL]]
778 ; CGSCC: Function Attrs: nosync
779 ; CGSCC-LABEL: define {{[^@]+}}@exclusion_set3
780 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR5]] {
781 ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
782 ; CGSCC-NEXT: store i32 3, ptr [[A]], align 4
783 ; CGSCC-NEXT: call void @exclusion_set3_helper(i1 noundef [[C]], ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
784 ; CGSCC-NEXT: [[FINAL:%.*]] = load i32, ptr [[A]], align 4
785 ; CGSCC-NEXT: ret i32 [[FINAL]]
789 call void @exclusion_set3_helper(i1 %c, ptr %a)
790 %final = load i32, ptr %a
796 define internal i32 @readI32(ptr %a) {
797 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: none)
798 ; TUNIT-LABEL: define {{[^@]+}}@readI32
799 ; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR9:[0-9]+]] {
800 ; TUNIT-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4
801 ; TUNIT-NEXT: store i32 [[TMP0]], ptr [[A_PRIV]], align 4
802 ; TUNIT-NEXT: [[R:%.*]] = load i32, ptr [[A_PRIV]], align 4
803 ; TUNIT-NEXT: store i32 1, ptr @B, align 4
804 ; TUNIT-NEXT: ret i32 [[R]]
806 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
807 ; CGSCC-LABEL: define {{[^@]+}}@readI32
808 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR9:[0-9]+]] {
809 ; CGSCC-NEXT: [[R:%.*]] = load i32, ptr [[A]], align 4
810 ; CGSCC-NEXT: store i32 1, ptr @B, align 4
811 ; CGSCC-NEXT: ret i32 [[R]]
813 %r = load i32, ptr %a
818 define internal i32 @broker(ptr %a) {
819 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: none)
820 ; TUNIT-LABEL: define {{[^@]+}}@broker
821 ; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR9]] {
822 ; TUNIT-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4
823 ; TUNIT-NEXT: store i32 [[TMP0]], ptr [[A_PRIV]], align 4
824 ; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr [[A_PRIV]], align 4
825 ; TUNIT-NEXT: [[R:%.*]] = call i32 @readI32(i32 [[TMP2]]) #[[ATTR13:[0-9]+]]
826 ; TUNIT-NEXT: ret i32 [[R]]
828 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(readwrite, argmem: none)
829 ; CGSCC-LABEL: define {{[^@]+}}@broker
830 ; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR10:[0-9]+]] {
831 ; CGSCC-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4
832 ; CGSCC-NEXT: store i32 [[TMP0]], ptr [[A_PRIV]], align 4
833 ; CGSCC-NEXT: [[R:%.*]] = call i32 @readI32(ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_PRIV]]) #[[ATTR14:[0-9]+]]
834 ; CGSCC-NEXT: ret i32 [[R]]
836 %r = call i32 @readI32(ptr %a)
840 ; FIXME: This function should return 1, not 0
841 define i32 @two_calls() {
842 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
843 ; TUNIT-LABEL: define {{[^@]+}}@two_calls
844 ; TUNIT-SAME: () #[[ATTR10:[0-9]+]] {
845 ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
846 ; TUNIT-NEXT: store i32 0, ptr [[A]], align 4
847 ; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4
848 ; TUNIT-NEXT: [[D:%.*]] = call i32 @broker(i32 [[TMP1]]) #[[ATTR13]]
849 ; TUNIT-NEXT: store i32 1, ptr [[A]], align 4
850 ; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr [[A]], align 4
851 ; TUNIT-NEXT: [[R:%.*]] = call i32 @broker(i32 [[TMP2]]) #[[ATTR13]]
852 ; TUNIT-NEXT: ret i32 [[R]]
854 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
855 ; CGSCC-LABEL: define {{[^@]+}}@two_calls
856 ; CGSCC-SAME: () #[[ATTR11:[0-9]+]] {
857 ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
858 ; CGSCC-NEXT: store i32 0, ptr [[A]], align 4
859 ; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4
860 ; CGSCC-NEXT: [[D:%.*]] = call i32 @broker(i32 noundef [[TMP1]]) #[[ATTR14]]
861 ; CGSCC-NEXT: store i32 1, ptr [[A]], align 4
862 ; CGSCC-NEXT: [[R:%.*]] = call i32 @broker(i32 noundef 1) #[[ATTR14]]
863 ; CGSCC-NEXT: ret i32 [[R]]
867 %d = call i32 @broker(ptr %a)
869 %r = call i32 @broker(ptr %a)
874 ; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
875 ; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nocallback nosync }
876 ; TUNIT: attributes #[[ATTR2:[0-9]+]] = { allockind("free") "alloc-family"="malloc" }
877 ; TUNIT: attributes #[[ATTR3:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" }
878 ; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
879 ; TUNIT: attributes #[[ATTR5]] = { norecurse nosync }
880 ; TUNIT: attributes #[[ATTR6]] = { nocallback }
881 ; TUNIT: attributes #[[ATTR7]] = { norecurse }
882 ; TUNIT: attributes #[[ATTR8]] = { nosync }
883 ; TUNIT: attributes #[[ATTR9]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: none) }
884 ; TUNIT: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn }
885 ; TUNIT: attributes #[[ATTR11:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
886 ; TUNIT: attributes #[[ATTR12]] = { nosync nounwind memory(write) }
887 ; TUNIT: attributes #[[ATTR13]] = { nofree nosync nounwind willreturn }
889 ; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
890 ; CGSCC: attributes #[[ATTR1:[0-9]+]] = { nocallback nosync }
891 ; CGSCC: attributes #[[ATTR2:[0-9]+]] = { allockind("free") "alloc-family"="malloc" }
892 ; CGSCC: attributes #[[ATTR3:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" }
893 ; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
894 ; CGSCC: attributes #[[ATTR5]] = { nosync }
895 ; CGSCC: attributes #[[ATTR6]] = { norecurse nosync }
896 ; CGSCC: attributes #[[ATTR7]] = { nocallback }
897 ; CGSCC: attributes #[[ATTR8]] = { norecurse }
898 ; CGSCC: attributes #[[ATTR9]] = { mustprogress nofree norecurse nosync nounwind willreturn }
899 ; CGSCC: attributes #[[ATTR10]] = { mustprogress nofree nosync nounwind willreturn memory(readwrite, argmem: none) }
900 ; CGSCC: attributes #[[ATTR11]] = { mustprogress nofree nosync nounwind willreturn }
901 ; CGSCC: attributes #[[ATTR12:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
902 ; CGSCC: attributes #[[ATTR13]] = { nounwind memory(write) }
903 ; CGSCC: attributes #[[ATTR14]] = { nofree nounwind willreturn }