1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
2 ; RUN: opt < %s -passes=function-attrs -S | FileCheck --check-prefixes=COMMON,FNATTRS %s
3 ; RUN: opt < %s -passes=attributor-light -S | FileCheck --check-prefixes=COMMON,ATTRIBUTOR %s
4 ; RUN: opt < %s -passes=attributor-light-cgscc -S | FileCheck --check-prefixes=COMMON,ATTRIBUTOR-CGSCC %s
8 declare void @test1_1(ptr %x1_1, ptr nocapture readonly %y1_1, ...)
10 define void @test1_2(ptr %x1_2, ptr %y1_2, ptr %z1_2) {
11 ; FNATTRS-LABEL: define {{[^@]+}}@test1_2
12 ; FNATTRS-SAME: (ptr [[X1_2:%.*]], ptr nocapture readonly [[Y1_2:%.*]], ptr [[Z1_2:%.*]]) {
13 ; FNATTRS-NEXT: call void (ptr, ptr, ...) @test1_1(ptr [[X1_2]], ptr [[Y1_2]], ptr [[Z1_2]])
14 ; FNATTRS-NEXT: store i32 0, ptr @x, align 4
15 ; FNATTRS-NEXT: ret void
17 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test1_2
18 ; ATTRIBUTOR-SAME: (ptr [[X1_2:%.*]], ptr nocapture nofree readonly [[Y1_2:%.*]], ptr [[Z1_2:%.*]]) {
19 ; ATTRIBUTOR-NEXT: call void (ptr, ptr, ...) @test1_1(ptr [[X1_2]], ptr nocapture nofree readonly [[Y1_2]], ptr [[Z1_2]])
20 ; ATTRIBUTOR-NEXT: store i32 0, ptr @x, align 4
21 ; ATTRIBUTOR-NEXT: ret void
23 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test1_2
24 ; ATTRIBUTOR-CGSCC-SAME: (ptr [[X1_2:%.*]], ptr nocapture nofree readonly [[Y1_2:%.*]], ptr [[Z1_2:%.*]]) {
25 ; ATTRIBUTOR-CGSCC-NEXT: call void (ptr, ptr, ...) @test1_1(ptr [[X1_2]], ptr nocapture nofree readonly [[Y1_2]], ptr [[Z1_2]])
26 ; ATTRIBUTOR-CGSCC-NEXT: store i32 0, ptr @x, align 4
27 ; ATTRIBUTOR-CGSCC-NEXT: ret void
29 call void (ptr, ptr, ...) @test1_1(ptr %x1_2, ptr %y1_2, ptr %z1_2)
34 ; TODO: Missing with attributor-light: argmem: none, inaccessiblemem: none
35 define ptr @test2(ptr %p) {
36 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
37 ; FNATTRS-LABEL: define {{[^@]+}}@test2
38 ; FNATTRS-SAME: (ptr readnone returned [[P:%.*]]) #[[ATTR0:[0-9]+]] {
39 ; FNATTRS-NEXT: store i32 0, ptr @x, align 4
40 ; FNATTRS-NEXT: ret ptr [[P]]
42 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
43 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test2
44 ; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0:[0-9]+]] {
45 ; ATTRIBUTOR-NEXT: store i32 0, ptr @x, align 4
46 ; ATTRIBUTOR-NEXT: ret ptr [[P]]
48 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
49 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test2
50 ; ATTRIBUTOR-CGSCC-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0:[0-9]+]] {
51 ; ATTRIBUTOR-CGSCC-NEXT: store i32 0, ptr @x, align 4
52 ; ATTRIBUTOR-CGSCC-NEXT: ret ptr [[P]]
58 define i1 @test3(ptr %p, ptr %q) {
59 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
60 ; FNATTRS-LABEL: define {{[^@]+}}@test3
61 ; FNATTRS-SAME: (ptr readnone [[P:%.*]], ptr readnone [[Q:%.*]]) #[[ATTR1:[0-9]+]] {
62 ; FNATTRS-NEXT: [[A:%.*]] = icmp ult ptr [[P]], [[Q]]
63 ; FNATTRS-NEXT: ret i1 [[A]]
65 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
66 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test3
67 ; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]], ptr nofree readnone [[Q:%.*]]) #[[ATTR1:[0-9]+]] {
68 ; ATTRIBUTOR-NEXT: [[A:%.*]] = icmp ult ptr [[P]], [[Q]]
69 ; ATTRIBUTOR-NEXT: ret i1 [[A]]
71 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
72 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test3
73 ; ATTRIBUTOR-CGSCC-SAME: (ptr nofree readnone [[P:%.*]], ptr nofree readnone [[Q:%.*]]) #[[ATTR1:[0-9]+]] {
74 ; ATTRIBUTOR-CGSCC-NEXT: [[A:%.*]] = icmp ult ptr [[P]], [[Q]]
75 ; ATTRIBUTOR-CGSCC-NEXT: ret i1 [[A]]
77 %A = icmp ult ptr %p, %q
81 declare void @test4_1(ptr nocapture) readonly
83 define void @test4_2(ptr %p) {
84 ; FNATTRS: Function Attrs: nofree memory(read)
85 ; FNATTRS-LABEL: define {{[^@]+}}@test4_2
86 ; FNATTRS-SAME: (ptr nocapture readonly [[P:%.*]]) #[[ATTR3:[0-9]+]] {
87 ; FNATTRS-NEXT: call void @test4_1(ptr [[P]])
88 ; FNATTRS-NEXT: ret void
90 ; ATTRIBUTOR: Function Attrs: nosync memory(read)
91 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test4_2
92 ; ATTRIBUTOR-SAME: (ptr nocapture readonly [[P:%.*]]) #[[ATTR3:[0-9]+]] {
93 ; ATTRIBUTOR-NEXT: call void @test4_1(ptr nocapture readonly [[P]]) #[[ATTR3]]
94 ; ATTRIBUTOR-NEXT: ret void
96 ; ATTRIBUTOR-CGSCC: Function Attrs: nosync memory(read)
97 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test4_2
98 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture readonly [[P:%.*]]) #[[ATTR3:[0-9]+]] {
99 ; ATTRIBUTOR-CGSCC-NEXT: call void @test4_1(ptr nocapture readonly [[P]]) #[[ATTR3]]
100 ; ATTRIBUTOR-CGSCC-NEXT: ret void
102 call void @test4_1(ptr %p)
106 ; Missed optz'n: we could make %q readnone, but don't break test6!
107 define void @test5(ptr %p, ptr %q) {
108 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
109 ; FNATTRS-LABEL: define {{[^@]+}}@test5
110 ; FNATTRS-SAME: (ptr nocapture writeonly initializes((0, 8)) [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR4:[0-9]+]] {
111 ; FNATTRS-NEXT: store ptr [[Q]], ptr [[P]], align 8
112 ; FNATTRS-NEXT: ret void
114 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
115 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test5
116 ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull writeonly [[P:%.*]], ptr nofree writeonly [[Q:%.*]]) #[[ATTR4:[0-9]+]] {
117 ; ATTRIBUTOR-NEXT: store ptr [[Q]], ptr [[P]], align 8
118 ; ATTRIBUTOR-NEXT: ret void
120 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
121 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test5
122 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree nonnull writeonly [[P:%.*]], ptr nofree writeonly [[Q:%.*]]) #[[ATTR4:[0-9]+]] {
123 ; ATTRIBUTOR-CGSCC-NEXT: store ptr [[Q]], ptr [[P]], align 8
124 ; ATTRIBUTOR-CGSCC-NEXT: ret void
130 declare void @test6_1()
132 ; This is not a missed optz'n.
133 define void @test6_2(ptr %p, ptr %q) {
134 ; FNATTRS-LABEL: define {{[^@]+}}@test6_2
135 ; FNATTRS-SAME: (ptr nocapture writeonly initializes((0, 8)) [[P:%.*]], ptr [[Q:%.*]]) {
136 ; FNATTRS-NEXT: store ptr [[Q]], ptr [[P]], align 8
137 ; FNATTRS-NEXT: call void @test6_1()
138 ; FNATTRS-NEXT: ret void
140 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test6_2
141 ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull writeonly [[P:%.*]], ptr nofree [[Q:%.*]]) {
142 ; ATTRIBUTOR-NEXT: store ptr [[Q]], ptr [[P]], align 8
143 ; ATTRIBUTOR-NEXT: call void @test6_1()
144 ; ATTRIBUTOR-NEXT: ret void
146 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test6_2
147 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree nonnull writeonly [[P:%.*]], ptr nofree [[Q:%.*]]) {
148 ; ATTRIBUTOR-CGSCC-NEXT: store ptr [[Q]], ptr [[P]], align 8
149 ; ATTRIBUTOR-CGSCC-NEXT: call void @test6_1()
150 ; ATTRIBUTOR-CGSCC-NEXT: ret void
157 ; inalloca parameters are always considered written
158 define void @test7_1(ptr inalloca(i32) %a) {
159 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
160 ; FNATTRS-LABEL: define {{[^@]+}}@test7_1
161 ; FNATTRS-SAME: (ptr nocapture inalloca(i32) [[A:%.*]]) #[[ATTR5:[0-9]+]] {
162 ; FNATTRS-NEXT: ret void
164 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
165 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test7_1
166 ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull writeonly inalloca(i32) [[A:%.*]]) #[[ATTR1]] {
167 ; ATTRIBUTOR-NEXT: ret void
169 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
170 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test7_1
171 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree nonnull writeonly inalloca(i32) [[A:%.*]]) #[[ATTR1]] {
172 ; ATTRIBUTOR-CGSCC-NEXT: ret void
177 ; preallocated parameters are always considered written
178 define void @test7_2(ptr preallocated(i32) %a) {
179 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
180 ; FNATTRS-LABEL: define {{[^@]+}}@test7_2
181 ; FNATTRS-SAME: (ptr nocapture preallocated(i32) [[A:%.*]]) #[[ATTR5]] {
182 ; FNATTRS-NEXT: ret void
184 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
185 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test7_2
186 ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull writeonly preallocated(i32) [[A:%.*]]) #[[ATTR1]] {
187 ; ATTRIBUTOR-NEXT: ret void
189 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
190 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test7_2
191 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree nonnull writeonly preallocated(i32) [[A:%.*]]) #[[ATTR1]] {
192 ; ATTRIBUTOR-CGSCC-NEXT: ret void
197 define ptr @test8_1(ptr %p) {
198 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
199 ; FNATTRS-LABEL: define {{[^@]+}}@test8_1
200 ; FNATTRS-SAME: (ptr readnone returned [[P:%.*]]) #[[ATTR1]] {
201 ; FNATTRS-NEXT: entry:
202 ; FNATTRS-NEXT: ret ptr [[P]]
204 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
205 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test8_1
206 ; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR1]] {
207 ; ATTRIBUTOR-NEXT: entry:
208 ; ATTRIBUTOR-NEXT: ret ptr [[P]]
210 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
211 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test8_1
212 ; ATTRIBUTOR-CGSCC-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR1]] {
213 ; ATTRIBUTOR-CGSCC-NEXT: entry:
214 ; ATTRIBUTOR-CGSCC-NEXT: ret ptr [[P]]
220 define void @test8_2(ptr %p) {
221 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
222 ; FNATTRS-LABEL: define {{[^@]+}}@test8_2
223 ; FNATTRS-SAME: (ptr writeonly [[P:%.*]]) #[[ATTR4]] {
224 ; FNATTRS-NEXT: entry:
225 ; FNATTRS-NEXT: [[CALL:%.*]] = call ptr @test8_1(ptr [[P]])
226 ; FNATTRS-NEXT: store i32 10, ptr [[CALL]], align 4
227 ; FNATTRS-NEXT: ret void
229 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
230 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test8_2
231 ; ATTRIBUTOR-SAME: (ptr nocapture nofree writeonly [[P:%.*]]) #[[ATTR0]] {
232 ; ATTRIBUTOR-NEXT: entry:
233 ; ATTRIBUTOR-NEXT: [[CALL:%.*]] = call ptr @test8_1(ptr nofree readnone [[P]]) #[[ATTR14:[0-9]+]]
234 ; ATTRIBUTOR-NEXT: store i32 10, ptr [[CALL]], align 4
235 ; ATTRIBUTOR-NEXT: ret void
237 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)
238 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test8_2
239 ; ATTRIBUTOR-CGSCC-SAME: (ptr nofree writeonly [[P:%.*]]) #[[ATTR5:[0-9]+]] {
240 ; ATTRIBUTOR-CGSCC-NEXT: entry:
241 ; ATTRIBUTOR-CGSCC-NEXT: [[CALL:%.*]] = call ptr @test8_1(ptr nofree readnone [[P]]) #[[ATTR14:[0-9]+]]
242 ; ATTRIBUTOR-CGSCC-NEXT: store i32 10, ptr [[CALL]], align 4
243 ; ATTRIBUTOR-CGSCC-NEXT: ret void
246 %call = call ptr @test8_1(ptr %p)
247 store i32 10, ptr %call, align 4
251 declare void @llvm.masked.scatter.v4i32.v4p0(<4 x i32>%val, <4 x ptr>, i32, <4 x i1>)
253 define void @test9(<4 x ptr> %ptrs, <4 x i32>%val) {
254 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
255 ; FNATTRS-LABEL: define {{[^@]+}}@test9
256 ; FNATTRS-SAME: (<4 x ptr> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR7:[0-9]+]] {
257 ; FNATTRS-NEXT: call void @llvm.masked.scatter.v4i32.v4p0(<4 x i32> [[VAL]], <4 x ptr> [[PTRS]], i32 4, <4 x i1> <i1 true, i1 false, i1 true, i1 false>)
258 ; FNATTRS-NEXT: ret void
260 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
261 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test9
262 ; ATTRIBUTOR-SAME: (<4 x ptr> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] {
263 ; ATTRIBUTOR-NEXT: call void @llvm.masked.scatter.v4i32.v4p0(<4 x i32> [[VAL]], <4 x ptr> [[PTRS]], i32 4, <4 x i1> <i1 true, i1 false, i1 true, i1 false>) #[[ATTR15:[0-9]+]]
264 ; ATTRIBUTOR-NEXT: ret void
266 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
267 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test9
268 ; ATTRIBUTOR-CGSCC-SAME: (<4 x ptr> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] {
269 ; ATTRIBUTOR-CGSCC-NEXT: call void @llvm.masked.scatter.v4i32.v4p0(<4 x i32> [[VAL]], <4 x ptr> [[PTRS]], i32 4, <4 x i1> <i1 true, i1 false, i1 true, i1 false>) #[[ATTR15:[0-9]+]]
270 ; ATTRIBUTOR-CGSCC-NEXT: ret void
272 call void @llvm.masked.scatter.v4i32.v4p0(<4 x i32>%val, <4 x ptr> %ptrs, i32 4, <4 x i1><i1 true, i1 false, i1 true, i1 false>)
276 declare <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr>, i32, <4 x i1>, <4 x i32>)
277 define <4 x i32> @test10(<4 x ptr> %ptrs) {
278 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
279 ; FNATTRS-LABEL: define {{[^@]+}}@test10
280 ; FNATTRS-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR9:[0-9]+]] {
281 ; FNATTRS-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> [[PTRS]], i32 4, <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> undef)
282 ; FNATTRS-NEXT: ret <4 x i32> [[RES]]
284 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
285 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test10
286 ; ATTRIBUTOR-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR7:[0-9]+]] {
287 ; ATTRIBUTOR-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> [[PTRS]], i32 4, <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> undef) #[[ATTR16:[0-9]+]]
288 ; ATTRIBUTOR-NEXT: ret <4 x i32> [[RES]]
290 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
291 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test10
292 ; ATTRIBUTOR-CGSCC-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR8:[0-9]+]] {
293 ; ATTRIBUTOR-CGSCC-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> [[PTRS]], i32 4, <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> undef) #[[ATTR16:[0-9]+]]
294 ; ATTRIBUTOR-CGSCC-NEXT: ret <4 x i32> [[RES]]
296 %res = call <4 x i32> @llvm.masked.gather.v4i32.v4p0(<4 x ptr> %ptrs, i32 4, <4 x i1><i1 true, i1 false, i1 true, i1 false>, <4 x i32>undef)
300 declare <4 x i32> @test11_1(<4 x ptr>) argmemonly nounwind readonly
301 define <4 x i32> @test11_2(<4 x ptr> %ptrs) {
302 ; FNATTRS: Function Attrs: nofree nounwind memory(argmem: read)
303 ; FNATTRS-LABEL: define {{[^@]+}}@test11_2
304 ; FNATTRS-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR11:[0-9]+]] {
305 ; FNATTRS-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x ptr> [[PTRS]])
306 ; FNATTRS-NEXT: ret <4 x i32> [[RES]]
308 ; ATTRIBUTOR: Function Attrs: nosync nounwind memory(argmem: read)
309 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test11_2
310 ; ATTRIBUTOR-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR9:[0-9]+]] {
311 ; ATTRIBUTOR-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x ptr> [[PTRS]]) #[[ATTR3]]
312 ; ATTRIBUTOR-NEXT: ret <4 x i32> [[RES]]
314 ; ATTRIBUTOR-CGSCC: Function Attrs: nosync nounwind memory(argmem: read)
315 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test11_2
316 ; ATTRIBUTOR-CGSCC-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR10:[0-9]+]] {
317 ; ATTRIBUTOR-CGSCC-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x ptr> [[PTRS]]) #[[ATTR3]]
318 ; ATTRIBUTOR-CGSCC-NEXT: ret <4 x i32> [[RES]]
320 %res = call <4 x i32> @test11_1(<4 x ptr> %ptrs)
324 declare <4 x i32> @test12_1(<4 x ptr>) argmemonly nounwind
325 define <4 x i32> @test12_2(<4 x ptr> %ptrs) {
326 ; FNATTRS: Function Attrs: nounwind memory(argmem: readwrite)
327 ; FNATTRS-LABEL: define {{[^@]+}}@test12_2
328 ; FNATTRS-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR12:[0-9]+]] {
329 ; FNATTRS-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x ptr> [[PTRS]])
330 ; FNATTRS-NEXT: ret <4 x i32> [[RES]]
332 ; ATTRIBUTOR: Function Attrs: nounwind memory(argmem: readwrite)
333 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test12_2
334 ; ATTRIBUTOR-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR10:[0-9]+]] {
335 ; ATTRIBUTOR-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x ptr> [[PTRS]])
336 ; ATTRIBUTOR-NEXT: ret <4 x i32> [[RES]]
338 ; ATTRIBUTOR-CGSCC: Function Attrs: nounwind memory(argmem: readwrite)
339 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@test12_2
340 ; ATTRIBUTOR-CGSCC-SAME: (<4 x ptr> [[PTRS:%.*]]) #[[ATTR11:[0-9]+]] {
341 ; ATTRIBUTOR-CGSCC-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x ptr> [[PTRS]])
342 ; ATTRIBUTOR-CGSCC-NEXT: ret <4 x i32> [[RES]]
344 %res = call <4 x i32> @test12_1(<4 x ptr> %ptrs)
348 define i32 @volatile_load(ptr %p) {
349 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite)
350 ; FNATTRS-LABEL: define {{[^@]+}}@volatile_load
351 ; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR13:[0-9]+]] {
352 ; FNATTRS-NEXT: [[LOAD:%.*]] = load volatile i32, ptr [[P]], align 4
353 ; FNATTRS-NEXT: ret i32 [[LOAD]]
355 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
356 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@volatile_load
357 ; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]]) #[[ATTR11:[0-9]+]] {
358 ; ATTRIBUTOR-NEXT: [[LOAD:%.*]] = load volatile i32, ptr [[P]], align 4
359 ; ATTRIBUTOR-NEXT: ret i32 [[LOAD]]
361 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
362 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@volatile_load
363 ; ATTRIBUTOR-CGSCC-SAME: (ptr nofree [[P:%.*]]) #[[ATTR12:[0-9]+]] {
364 ; ATTRIBUTOR-CGSCC-NEXT: [[LOAD:%.*]] = load volatile i32, ptr [[P]], align 4
365 ; ATTRIBUTOR-CGSCC-NEXT: ret i32 [[LOAD]]
367 %load = load volatile i32, ptr %p
371 declare void @escape_readnone_ptr(ptr %addr, ptr readnone %ptr)
372 declare void @escape_readonly_ptr(ptr %addr, ptr readonly %ptr)
374 ; The argument pointer %escaped_then_written cannot be marked readnone/only even
375 ; though the only direct use, in @escape_readnone_ptr/@escape_readonly_ptr,
376 ; is marked as readnone/only. However, the functions can write the pointer into
377 ; %addr, causing the store to write to %escaped_then_written.
378 define void @unsound_readnone(ptr %ignored, ptr %escaped_then_written) {
379 ; FNATTRS-LABEL: define {{[^@]+}}@unsound_readnone
380 ; FNATTRS-SAME: (ptr nocapture readnone [[IGNORED:%.*]], ptr [[ESCAPED_THEN_WRITTEN:%.*]]) {
381 ; FNATTRS-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
382 ; FNATTRS-NEXT: call void @escape_readnone_ptr(ptr [[ADDR]], ptr [[ESCAPED_THEN_WRITTEN]])
383 ; FNATTRS-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
384 ; FNATTRS-NEXT: store i8 0, ptr [[ADDR_LD]], align 1
385 ; FNATTRS-NEXT: ret void
387 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@unsound_readnone
388 ; ATTRIBUTOR-SAME: (ptr nocapture nofree readnone [[IGNORED:%.*]], ptr nofree [[ESCAPED_THEN_WRITTEN:%.*]]) {
389 ; ATTRIBUTOR-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
390 ; ATTRIBUTOR-NEXT: call void @escape_readnone_ptr(ptr [[ADDR]], ptr nofree [[ESCAPED_THEN_WRITTEN]])
391 ; ATTRIBUTOR-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
392 ; ATTRIBUTOR-NEXT: store i8 0, ptr [[ADDR_LD]], align 1
393 ; ATTRIBUTOR-NEXT: ret void
395 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@unsound_readnone
396 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree readnone [[IGNORED:%.*]], ptr nofree [[ESCAPED_THEN_WRITTEN:%.*]]) {
397 ; ATTRIBUTOR-CGSCC-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
398 ; ATTRIBUTOR-CGSCC-NEXT: call void @escape_readnone_ptr(ptr [[ADDR]], ptr nofree [[ESCAPED_THEN_WRITTEN]])
399 ; ATTRIBUTOR-CGSCC-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
400 ; ATTRIBUTOR-CGSCC-NEXT: store i8 0, ptr [[ADDR_LD]], align 1
401 ; ATTRIBUTOR-CGSCC-NEXT: ret void
404 call void @escape_readnone_ptr(ptr %addr, ptr %escaped_then_written)
405 %addr.ld = load ptr, ptr %addr
406 store i8 0, ptr %addr.ld
410 define void @unsound_readonly(ptr %ignored, ptr %escaped_then_written) {
411 ; FNATTRS-LABEL: define {{[^@]+}}@unsound_readonly
412 ; FNATTRS-SAME: (ptr nocapture readnone [[IGNORED:%.*]], ptr [[ESCAPED_THEN_WRITTEN:%.*]]) {
413 ; FNATTRS-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
414 ; FNATTRS-NEXT: call void @escape_readonly_ptr(ptr [[ADDR]], ptr [[ESCAPED_THEN_WRITTEN]])
415 ; FNATTRS-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
416 ; FNATTRS-NEXT: store i8 0, ptr [[ADDR_LD]], align 1
417 ; FNATTRS-NEXT: ret void
419 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@unsound_readonly
420 ; ATTRIBUTOR-SAME: (ptr nocapture nofree readnone [[IGNORED:%.*]], ptr nofree [[ESCAPED_THEN_WRITTEN:%.*]]) {
421 ; ATTRIBUTOR-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
422 ; ATTRIBUTOR-NEXT: call void @escape_readonly_ptr(ptr [[ADDR]], ptr nofree [[ESCAPED_THEN_WRITTEN]])
423 ; ATTRIBUTOR-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
424 ; ATTRIBUTOR-NEXT: store i8 0, ptr [[ADDR_LD]], align 1
425 ; ATTRIBUTOR-NEXT: ret void
427 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@unsound_readonly
428 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree readnone [[IGNORED:%.*]], ptr nofree [[ESCAPED_THEN_WRITTEN:%.*]]) {
429 ; ATTRIBUTOR-CGSCC-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
430 ; ATTRIBUTOR-CGSCC-NEXT: call void @escape_readonly_ptr(ptr [[ADDR]], ptr nofree [[ESCAPED_THEN_WRITTEN]])
431 ; ATTRIBUTOR-CGSCC-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
432 ; ATTRIBUTOR-CGSCC-NEXT: store i8 0, ptr [[ADDR_LD]], align 1
433 ; ATTRIBUTOR-CGSCC-NEXT: ret void
436 call void @escape_readonly_ptr(ptr %addr, ptr %escaped_then_written)
437 %addr.ld = load ptr, ptr %addr
438 store i8 0, ptr %addr.ld
442 define void @fptr_test1a(ptr %p, ptr %f) {
443 ; FNATTRS-LABEL: define {{[^@]+}}@fptr_test1a
444 ; FNATTRS-SAME: (ptr nocapture readnone [[P:%.*]], ptr nocapture readonly [[F:%.*]]) {
445 ; FNATTRS-NEXT: call void [[F]](ptr nocapture readnone [[P]])
446 ; FNATTRS-NEXT: ret void
448 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test1a
449 ; ATTRIBUTOR-SAME: (ptr nocapture nofree [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) {
450 ; ATTRIBUTOR-NEXT: call void [[F]](ptr nocapture nofree readnone [[P]])
451 ; ATTRIBUTOR-NEXT: ret void
453 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@fptr_test1a
454 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) {
455 ; ATTRIBUTOR-CGSCC-NEXT: call void [[F]](ptr nocapture nofree readnone [[P]])
456 ; ATTRIBUTOR-CGSCC-NEXT: ret void
458 call void %f(ptr nocapture readnone %p)
462 ; Can't infer readnone here because call might capture %p
463 define void @fptr_test1b(ptr %p, ptr %f) {
464 ; FNATTRS-LABEL: define {{[^@]+}}@fptr_test1b
465 ; FNATTRS-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[F:%.*]]) {
466 ; FNATTRS-NEXT: call void [[F]](ptr readnone [[P]])
467 ; FNATTRS-NEXT: ret void
469 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test1b
470 ; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) {
471 ; ATTRIBUTOR-NEXT: call void [[F]](ptr nofree readnone [[P]])
472 ; ATTRIBUTOR-NEXT: ret void
474 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@fptr_test1b
475 ; ATTRIBUTOR-CGSCC-SAME: (ptr nofree [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) {
476 ; ATTRIBUTOR-CGSCC-NEXT: call void [[F]](ptr nofree readnone [[P]])
477 ; ATTRIBUTOR-CGSCC-NEXT: ret void
479 call void %f(ptr readnone %p)
483 define void @fptr_test1c(ptr %p, ptr %f) {
484 ; FNATTRS: Function Attrs: nofree memory(read)
485 ; FNATTRS-LABEL: define {{[^@]+}}@fptr_test1c
486 ; FNATTRS-SAME: (ptr readnone [[P:%.*]], ptr nocapture readonly [[F:%.*]]) #[[ATTR3]] {
487 ; FNATTRS-NEXT: call void [[F]](ptr readnone [[P]]) #[[ATTR2:[0-9]+]]
488 ; FNATTRS-NEXT: ret void
490 ; ATTRIBUTOR: Function Attrs: memory(read)
491 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test1c
492 ; ATTRIBUTOR-SAME: (ptr nofree readonly [[P:%.*]], ptr nocapture nofree nonnull readonly [[F:%.*]]) #[[ATTR2:[0-9]+]] {
493 ; ATTRIBUTOR-NEXT: call void [[F]](ptr nofree readnone [[P]]) #[[ATTR2]]
494 ; ATTRIBUTOR-NEXT: ret void
496 ; ATTRIBUTOR-CGSCC: Function Attrs: memory(read)
497 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@fptr_test1c
498 ; ATTRIBUTOR-CGSCC-SAME: (ptr nofree readonly [[P:%.*]], ptr nocapture nofree nonnull readonly [[F:%.*]]) #[[ATTR2:[0-9]+]] {
499 ; ATTRIBUTOR-CGSCC-NEXT: call void [[F]](ptr nofree readnone [[P]]) #[[ATTR2]]
500 ; ATTRIBUTOR-CGSCC-NEXT: ret void
502 call void %f(ptr readnone %p) readonly
506 define void @fptr_test2a(ptr %p, ptr %f) {
507 ; FNATTRS-LABEL: define {{[^@]+}}@fptr_test2a
508 ; FNATTRS-SAME: (ptr nocapture readonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) {
509 ; FNATTRS-NEXT: call void [[F]](ptr nocapture readonly [[P]])
510 ; FNATTRS-NEXT: ret void
512 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test2a
513 ; ATTRIBUTOR-SAME: (ptr nocapture nofree [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) {
514 ; ATTRIBUTOR-NEXT: call void [[F]](ptr nocapture nofree readonly [[P]])
515 ; ATTRIBUTOR-NEXT: ret void
517 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@fptr_test2a
518 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) {
519 ; ATTRIBUTOR-CGSCC-NEXT: call void [[F]](ptr nocapture nofree readonly [[P]])
520 ; ATTRIBUTOR-CGSCC-NEXT: ret void
522 call void %f(ptr nocapture readonly %p)
526 define void @fptr_test2b(ptr %p, ptr %f) {
527 ; Can't infer readonly here because call might capture %p
528 ; FNATTRS-LABEL: define {{[^@]+}}@fptr_test2b
529 ; FNATTRS-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[F:%.*]]) {
530 ; FNATTRS-NEXT: call void [[F]](ptr readonly [[P]])
531 ; FNATTRS-NEXT: ret void
533 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test2b
534 ; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) {
535 ; ATTRIBUTOR-NEXT: call void [[F]](ptr nofree readonly [[P]])
536 ; ATTRIBUTOR-NEXT: ret void
538 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@fptr_test2b
539 ; ATTRIBUTOR-CGSCC-SAME: (ptr nofree [[P:%.*]], ptr nocapture nofree nonnull [[F:%.*]]) {
540 ; ATTRIBUTOR-CGSCC-NEXT: call void [[F]](ptr nofree readonly [[P]])
541 ; ATTRIBUTOR-CGSCC-NEXT: ret void
543 call void %f(ptr readonly %p)
547 define void @fptr_test2c(ptr %p, ptr %f) {
548 ; FNATTRS: Function Attrs: nofree memory(read)
549 ; FNATTRS-LABEL: define {{[^@]+}}@fptr_test2c
550 ; FNATTRS-SAME: (ptr readonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) #[[ATTR3]] {
551 ; FNATTRS-NEXT: call void [[F]](ptr readonly [[P]]) #[[ATTR2]]
552 ; FNATTRS-NEXT: ret void
554 ; ATTRIBUTOR: Function Attrs: memory(read)
555 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test2c
556 ; ATTRIBUTOR-SAME: (ptr nofree readonly [[P:%.*]], ptr nocapture nofree nonnull readonly [[F:%.*]]) #[[ATTR2]] {
557 ; ATTRIBUTOR-NEXT: call void [[F]](ptr nofree readonly [[P]]) #[[ATTR2]]
558 ; ATTRIBUTOR-NEXT: ret void
560 ; ATTRIBUTOR-CGSCC: Function Attrs: memory(read)
561 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@fptr_test2c
562 ; ATTRIBUTOR-CGSCC-SAME: (ptr nofree readonly [[P:%.*]], ptr nocapture nofree nonnull readonly [[F:%.*]]) #[[ATTR2]] {
563 ; ATTRIBUTOR-CGSCC-NEXT: call void [[F]](ptr nofree readonly [[P]]) #[[ATTR2]]
564 ; ATTRIBUTOR-CGSCC-NEXT: ret void
566 call void %f(ptr readonly %p) readonly
570 define void @alloca_recphi() {
571 ; FNATTRS: Function Attrs: nofree norecurse nosync nounwind memory(none)
572 ; FNATTRS-LABEL: define {{[^@]+}}@alloca_recphi
573 ; FNATTRS-SAME: () #[[ATTR14:[0-9]+]] {
574 ; FNATTRS-NEXT: entry:
575 ; FNATTRS-NEXT: [[A:%.*]] = alloca [8 x i32], align 4
576 ; FNATTRS-NEXT: [[A_END:%.*]] = getelementptr i32, ptr [[A]], i64 8
577 ; FNATTRS-NEXT: br label [[LOOP:%.*]]
579 ; FNATTRS-NEXT: [[P:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[LOOP]] ]
580 ; FNATTRS-NEXT: store i32 0, ptr [[P]], align 4
581 ; FNATTRS-NEXT: [[TMP0:%.*]] = load i32, ptr [[P]], align 4
582 ; FNATTRS-NEXT: [[P_NEXT]] = getelementptr i32, ptr [[P]], i64 1
583 ; FNATTRS-NEXT: [[C:%.*]] = icmp ne ptr [[P_NEXT]], [[A_END]]
584 ; FNATTRS-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
586 ; FNATTRS-NEXT: ret void
588 ; ATTRIBUTOR: Function Attrs: nofree norecurse nosync nounwind memory(none)
589 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@alloca_recphi
590 ; ATTRIBUTOR-SAME: () #[[ATTR12:[0-9]+]] {
591 ; ATTRIBUTOR-NEXT: entry:
592 ; ATTRIBUTOR-NEXT: [[A:%.*]] = alloca [8 x i32], align 4
593 ; ATTRIBUTOR-NEXT: [[A_END:%.*]] = getelementptr i32, ptr [[A]], i64 8
594 ; ATTRIBUTOR-NEXT: br label [[LOOP:%.*]]
596 ; ATTRIBUTOR-NEXT: [[P:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[LOOP]] ]
597 ; ATTRIBUTOR-NEXT: store i32 0, ptr [[P]], align 4
598 ; ATTRIBUTOR-NEXT: [[TMP0:%.*]] = load i32, ptr [[P]], align 4
599 ; ATTRIBUTOR-NEXT: [[P_NEXT]] = getelementptr i32, ptr [[P]], i64 1
600 ; ATTRIBUTOR-NEXT: [[C:%.*]] = icmp ne ptr [[P_NEXT]], [[A_END]]
601 ; ATTRIBUTOR-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
603 ; ATTRIBUTOR-NEXT: ret void
605 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
606 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@alloca_recphi
607 ; ATTRIBUTOR-CGSCC-SAME: () #[[ATTR1]] {
608 ; ATTRIBUTOR-CGSCC-NEXT: entry:
609 ; ATTRIBUTOR-CGSCC-NEXT: [[A:%.*]] = alloca [8 x i32], align 4
610 ; ATTRIBUTOR-CGSCC-NEXT: [[A_END:%.*]] = getelementptr i32, ptr [[A]], i64 8
611 ; ATTRIBUTOR-CGSCC-NEXT: br label [[LOOP:%.*]]
612 ; ATTRIBUTOR-CGSCC: loop:
613 ; ATTRIBUTOR-CGSCC-NEXT: [[P:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[LOOP]] ]
614 ; ATTRIBUTOR-CGSCC-NEXT: store i32 0, ptr [[P]], align 4
615 ; ATTRIBUTOR-CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[P]], align 4
616 ; ATTRIBUTOR-CGSCC-NEXT: [[P_NEXT]] = getelementptr i32, ptr [[P]], i64 1
617 ; ATTRIBUTOR-CGSCC-NEXT: [[C:%.*]] = icmp ne ptr [[P_NEXT]], [[A_END]]
618 ; ATTRIBUTOR-CGSCC-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
619 ; ATTRIBUTOR-CGSCC: exit:
620 ; ATTRIBUTOR-CGSCC-NEXT: ret void
623 %a = alloca [8 x i32]
624 %a.end = getelementptr i32, ptr %a, i64 8
628 %p = phi ptr [ %a, %entry ], [ %p.next, %loop ]
631 %p.next = getelementptr i32, ptr %p, i64 1
632 %c = icmp ne ptr %p.next, %a.end
633 br i1 %c, label %loop, label %exit
639 declare void @readnone_param(ptr nocapture readnone %p)
640 declare void @readonly_param(ptr nocapture readonly %p)
642 ; FIXME: While this can't be readnone, this could be readonly.
643 define void @op_bundle_readnone_deopt(ptr %p) {
644 ; FNATTRS-LABEL: define {{[^@]+}}@op_bundle_readnone_deopt
645 ; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) {
646 ; FNATTRS-NEXT: call void @readnone_param(ptr [[P]]) [ "deopt"() ]
647 ; FNATTRS-NEXT: ret void
649 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@op_bundle_readnone_deopt
650 ; ATTRIBUTOR-SAME: (ptr nocapture nofree [[P:%.*]]) {
651 ; ATTRIBUTOR-NEXT: call void @readnone_param(ptr nocapture nofree [[P]]) [ "deopt"() ]
652 ; ATTRIBUTOR-NEXT: ret void
654 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@op_bundle_readnone_deopt
655 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree [[P:%.*]]) {
656 ; ATTRIBUTOR-CGSCC-NEXT: call void @readnone_param(ptr nocapture nofree [[P]]) [ "deopt"() ]
657 ; ATTRIBUTOR-CGSCC-NEXT: ret void
659 call void @readnone_param(ptr %p) ["deopt"()]
663 define void @op_bundle_readnone_unknown(ptr %p) {
664 ; FNATTRS-LABEL: define {{[^@]+}}@op_bundle_readnone_unknown
665 ; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) {
666 ; FNATTRS-NEXT: call void @readnone_param(ptr [[P]]) [ "unknown"() ]
667 ; FNATTRS-NEXT: ret void
669 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@op_bundle_readnone_unknown
670 ; ATTRIBUTOR-SAME: (ptr nocapture nofree [[P:%.*]]) {
671 ; ATTRIBUTOR-NEXT: call void @readnone_param(ptr nocapture nofree [[P]]) [ "unknown"() ]
672 ; ATTRIBUTOR-NEXT: ret void
674 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@op_bundle_readnone_unknown
675 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree [[P:%.*]]) {
676 ; ATTRIBUTOR-CGSCC-NEXT: call void @readnone_param(ptr nocapture nofree [[P]]) [ "unknown"() ]
677 ; ATTRIBUTOR-CGSCC-NEXT: ret void
679 call void @readnone_param(ptr %p) ["unknown"()]
683 define void @op_bundle_readonly_deopt(ptr %p) {
684 ; FNATTRS-LABEL: define {{[^@]+}}@op_bundle_readonly_deopt
685 ; FNATTRS-SAME: (ptr nocapture readonly [[P:%.*]]) {
686 ; FNATTRS-NEXT: call void @readonly_param(ptr [[P]]) [ "deopt"() ]
687 ; FNATTRS-NEXT: ret void
689 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@op_bundle_readonly_deopt
690 ; ATTRIBUTOR-SAME: (ptr nocapture nofree [[P:%.*]]) {
691 ; ATTRIBUTOR-NEXT: call void @readonly_param(ptr nocapture nofree [[P]]) [ "deopt"() ]
692 ; ATTRIBUTOR-NEXT: ret void
694 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@op_bundle_readonly_deopt
695 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree [[P:%.*]]) {
696 ; ATTRIBUTOR-CGSCC-NEXT: call void @readonly_param(ptr nocapture nofree [[P]]) [ "deopt"() ]
697 ; ATTRIBUTOR-CGSCC-NEXT: ret void
699 call void @readonly_param(ptr %p) ["deopt"()]
703 define void @op_bundle_readonly_unknown(ptr %p) {
704 ; FNATTRS-LABEL: define {{[^@]+}}@op_bundle_readonly_unknown
705 ; FNATTRS-SAME: (ptr nocapture [[P:%.*]]) {
706 ; FNATTRS-NEXT: call void @readonly_param(ptr [[P]]) [ "unknown"() ]
707 ; FNATTRS-NEXT: ret void
709 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@op_bundle_readonly_unknown
710 ; ATTRIBUTOR-SAME: (ptr nocapture nofree [[P:%.*]]) {
711 ; ATTRIBUTOR-NEXT: call void @readonly_param(ptr nocapture nofree [[P]]) [ "unknown"() ]
712 ; ATTRIBUTOR-NEXT: ret void
714 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@op_bundle_readonly_unknown
715 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree [[P:%.*]]) {
716 ; ATTRIBUTOR-CGSCC-NEXT: call void @readonly_param(ptr nocapture nofree [[P]]) [ "unknown"() ]
717 ; ATTRIBUTOR-CGSCC-NEXT: ret void
719 call void @readonly_param(ptr %p) ["unknown"()]
723 define i32 @writable_readonly(ptr writable dereferenceable(4) %p) {
724 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
725 ; FNATTRS-LABEL: define {{[^@]+}}@writable_readonly
726 ; FNATTRS-SAME: (ptr nocapture readonly dereferenceable(4) [[P:%.*]]) #[[ATTR15:[0-9]+]] {
727 ; FNATTRS-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 4
728 ; FNATTRS-NEXT: ret i32 [[V]]
730 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
731 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@writable_readonly
732 ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR13:[0-9]+]] {
733 ; ATTRIBUTOR-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 4
734 ; ATTRIBUTOR-NEXT: ret i32 [[V]]
736 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
737 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@writable_readonly
738 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR13:[0-9]+]] {
739 ; ATTRIBUTOR-CGSCC-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 4
740 ; ATTRIBUTOR-CGSCC-NEXT: ret i32 [[V]]
742 %v = load i32, ptr %p
746 define void @writable_readnone(ptr writable dereferenceable(4) %p) {
747 ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
748 ; FNATTRS-LABEL: define {{[^@]+}}@writable_readnone
749 ; FNATTRS-SAME: (ptr nocapture readnone dereferenceable(4) [[P:%.*]]) #[[ATTR1]] {
750 ; FNATTRS-NEXT: ret void
752 ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
753 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@writable_readnone
754 ; ATTRIBUTOR-SAME: (ptr nocapture nofree nonnull readnone dereferenceable(4) [[P:%.*]]) #[[ATTR1]] {
755 ; ATTRIBUTOR-NEXT: ret void
757 ; ATTRIBUTOR-CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
758 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@writable_readnone
759 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture nofree nonnull readnone dereferenceable(4) [[P:%.*]]) #[[ATTR1]] {
760 ; ATTRIBUTOR-CGSCC-NEXT: ret void
765 declare void @byval_param(ptr byval(i32) %p)
767 define void @call_byval_param(ptr %p) {
768 ; FNATTRS-LABEL: define {{[^@]+}}@call_byval_param
769 ; FNATTRS-SAME: (ptr nocapture readonly [[P:%.*]]) {
770 ; FNATTRS-NEXT: call void @byval_param(ptr byval(i32) [[P]])
771 ; FNATTRS-NEXT: ret void
773 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@call_byval_param
774 ; ATTRIBUTOR-SAME: (ptr nocapture readonly [[P:%.*]]) {
775 ; ATTRIBUTOR-NEXT: call void @byval_param(ptr nocapture readonly byval(i32) [[P]])
776 ; ATTRIBUTOR-NEXT: ret void
778 ; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@call_byval_param
779 ; ATTRIBUTOR-CGSCC-SAME: (ptr nocapture readonly [[P:%.*]]) {
780 ; ATTRIBUTOR-CGSCC-NEXT: call void @byval_param(ptr nocapture readonly byval(i32) [[P]])
781 ; ATTRIBUTOR-CGSCC-NEXT: ret void
783 call void @byval_param(ptr byval(i32) %p)
787 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: