2
2
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
3
3
target triple = "arm-apple-ios"
4
4
5
- declare void @llvm.memset.p0i8.i64 (i8* nocapture , i8 , i64 , i32 , i1 ) nounwind
6
- declare void @llvm.memcpy.p0i8.p0i8.i64 (i8* nocapture , i8* nocapture , i64 , i32 , i1 ) nounwind
5
+ declare void @llvm.memset.p0i8.i64 (i8* nocapture writeonly , i8 , i64 , i32 , i1 ) # 0
6
+ declare void @llvm.memcpy.p0i8.p0i8.i64 (i8* nocapture writeonly , i8* nocapture readonly , i64 , i32 , i1 ) # 0
7
7
8
- declare void @a_readonly_func (i8 *) noinline nounwind readonly
9
- declare void @a_writeonly_func (i8 *) noinline nounwind writeonly
8
+ declare void @a_readonly_func (i8* ) # 1
9
+ declare void @a_writeonly_func (i8* ) # 2
10
10
11
- define void @test2 (i8* %P , i8* %Q ) nounwind ssp {
11
+ define void @test2 (i8* %P , i8* %Q ) # 3 {
12
12
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
13
13
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
14
14
ret void
@@ -24,7 +24,7 @@ define void @test2(i8* %P, i8* %Q) nounwind ssp {
24
24
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
25
25
}
26
26
27
- define void @test2a (i8* noalias %P , i8* noalias %Q ) nounwind ssp {
27
+ define void @test2a (i8* noalias %P , i8* noalias %Q ) # 3 {
28
28
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
29
29
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
30
30
ret void
@@ -40,7 +40,7 @@ define void @test2a(i8* noalias %P, i8* noalias %Q) nounwind ssp {
40
40
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
41
41
}
42
42
43
- define void @test2b (i8* noalias %P , i8* noalias %Q ) nounwind ssp {
43
+ define void @test2b (i8* noalias %P , i8* noalias %Q ) # 3 {
44
44
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
45
45
%R = getelementptr i8 , i8* %P , i64 12
46
46
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %R , i8* %Q , i64 12 , i32 1 , i1 false )
@@ -61,7 +61,7 @@ define void @test2b(i8* noalias %P, i8* noalias %Q) nounwind ssp {
61
61
; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
62
62
}
63
63
64
- define void @test2c (i8* noalias %P , i8* noalias %Q ) nounwind ssp {
64
+ define void @test2c (i8* noalias %P , i8* noalias %Q ) # 3 {
65
65
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
66
66
%R = getelementptr i8 , i8* %P , i64 11
67
67
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %R , i8* %Q , i64 12 , i32 1 , i1 false )
@@ -82,7 +82,7 @@ define void @test2c(i8* noalias %P, i8* noalias %Q) nounwind ssp {
82
82
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
83
83
}
84
84
85
- define void @test2d (i8* noalias %P , i8* noalias %Q ) nounwind ssp {
85
+ define void @test2d (i8* noalias %P , i8* noalias %Q ) # 3 {
86
86
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
87
87
%R = getelementptr i8 , i8* %P , i64 -12
88
88
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %R , i8* %Q , i64 12 , i32 1 , i1 false )
@@ -103,7 +103,7 @@ define void @test2d(i8* noalias %P, i8* noalias %Q) nounwind ssp {
103
103
; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
104
104
}
105
105
106
- define void @test2e (i8* noalias %P , i8* noalias %Q ) nounwind ssp {
106
+ define void @test2e (i8* noalias %P , i8* noalias %Q ) # 3 {
107
107
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
108
108
%R = getelementptr i8 , i8* %P , i64 -11
109
109
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %R , i8* %Q , i64 12 , i32 1 , i1 false )
@@ -124,7 +124,7 @@ define void @test2e(i8* noalias %P, i8* noalias %Q) nounwind ssp {
124
124
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
125
125
}
126
126
127
- define void @test3 (i8* %P , i8* %Q ) nounwind ssp {
127
+ define void @test3 (i8* %P , i8* %Q ) # 3 {
128
128
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 8 , i32 1 , i1 false )
129
129
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
130
130
ret void
@@ -140,7 +140,7 @@ define void @test3(i8* %P, i8* %Q) nounwind ssp {
140
140
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
141
141
}
142
142
143
- define void @test3a (i8* noalias %P , i8* noalias %Q ) nounwind ssp {
143
+ define void @test3a (i8* noalias %P , i8* noalias %Q ) # 3 {
144
144
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 8 , i32 1 , i1 false )
145
145
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
146
146
ret void
@@ -156,7 +156,7 @@ define void @test3a(i8* noalias %P, i8* noalias %Q) nounwind ssp {
156
156
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
157
157
}
158
158
159
- define void @test4 (i8* %P , i8* noalias %Q ) nounwind ssp {
159
+ define void @test4 (i8* %P , i8* noalias %Q ) # 3 {
160
160
tail call void @llvm.memset.p0i8.i64 (i8* %P , i8 42 , i64 8 , i32 1 , i1 false )
161
161
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
162
162
ret void
@@ -172,7 +172,7 @@ define void @test4(i8* %P, i8* noalias %Q) nounwind ssp {
172
172
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 false)
173
173
}
174
174
175
- define void @test5 (i8* %P , i8* %Q , i8* %R ) nounwind ssp {
175
+ define void @test5 (i8* %P , i8* %Q , i8* %R ) # 3 {
176
176
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %Q , i64 12 , i32 1 , i1 false )
177
177
tail call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %P , i8* %R , i64 12 , i32 1 , i1 false )
178
178
ret void
@@ -192,7 +192,7 @@ define void @test5(i8* %P, i8* %Q, i8* %R) nounwind ssp {
192
192
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
193
193
}
194
194
195
- define void @test6 (i8* %P ) nounwind ssp {
195
+ define void @test6 (i8* %P ) # 3 {
196
196
call void @llvm.memset.p0i8.i64 (i8* %P , i8 -51 , i64 32 , i32 8 , i1 false )
197
197
call void @a_readonly_func (i8* %P )
198
198
ret void
@@ -205,7 +205,7 @@ define void @test6(i8* %P) nounwind ssp {
205
205
; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i32 8, i1 false)
206
206
}
207
207
208
- define void @test7 (i8* %P ) nounwind ssp {
208
+ define void @test7 (i8* %P ) # 3 {
209
209
call void @a_writeonly_func (i8* %P )
210
210
call void @a_readonly_func (i8* %P )
211
211
ret void
@@ -218,9 +218,9 @@ define void @test7(i8* %P) nounwind ssp {
218
218
; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @a_writeonly_func(i8* %P)
219
219
}
220
220
221
- declare void @an_inaccessiblememonly_func () nounwind inaccessiblememonly
222
- declare void @an_inaccessibleorargmemonly_func (i8 *) nounwind inaccessiblemem_or_argmemonly
223
- declare void @an_argmemonly_func (i8 *) nounwind argmemonly
221
+ declare void @an_inaccessiblememonly_func () # 4
222
+ declare void @an_inaccessibleorargmemonly_func (i8* ) # 5
223
+ declare void @an_argmemonly_func (i8* ) # 0
224
224
225
225
define void @test8 (i8* %p ) {
226
226
entry:
@@ -260,3 +260,80 @@ entry:
260
260
; CHECK: NoModRef: call void @an_argmemonly_func(i8* %q) <-> call void @an_inaccessiblememonly_func()
261
261
; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
262
262
}
263
+
264
+ ;; test that unknown operand bundle has unknown effect to the heap
265
+ define void @test9 (i8* %p ) {
266
+ ; CHECK-LABEL: Function: test9
267
+ entry:
268
+ %q = getelementptr i8 , i8* %p , i64 16
269
+ call void @a_readonly_func (i8* %p ) [ "unknown" () ]
270
+ call void @an_inaccessiblememonly_func () [ "unknown" () ]
271
+ call void @an_inaccessibleorargmemonly_func (i8* %q ) [ "unknown" () ]
272
+ call void @an_argmemonly_func (i8* %q ) [ "unknown" () ]
273
+ ret void
274
+
275
+ ; CHECK: Both ModRef: Ptr: i8* %p <-> call void @a_readonly_func(i8* %p) [ "unknown"() ]
276
+ ; CHECK: Both ModRef: Ptr: i8* %q <-> call void @a_readonly_func(i8* %p) [ "unknown"() ]
277
+ ; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_inaccessiblememonly_func() [ "unknown"() ]
278
+ ; CHECK: Both ModRef: Ptr: i8* %q <-> call void @an_inaccessiblememonly_func() [ "unknown"() ]
279
+ ; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
280
+ ; CHECK: Both ModRef: Ptr: i8* %q <-> call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
281
+ ; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q) [ "unknown"() ]
282
+ ; CHECK: Both ModRef: Ptr: i8* %q <-> call void @an_argmemonly_func(i8* %q) [ "unknown"() ]
283
+ ; CHECK: Both ModRef: call void @a_readonly_func(i8* %p) [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() [ "unknown"() ]
284
+ ; CHECK: Both ModRef: call void @a_readonly_func(i8* %p) [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
285
+ ; CHECK: Both ModRef: call void @a_readonly_func(i8* %p) [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) [ "unknown"() ]
286
+ ; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) [ "unknown"() ]
287
+ ; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
288
+ ; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) [ "unknown"() ]
289
+ ; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) [ "unknown"() ]
290
+ ; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() [ "unknown"() ]
291
+ ; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) [ "unknown"() ]
292
+ ; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) [ "unknown"() ]
293
+ ; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() [ "unknown"() ]
294
+ ; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
295
+ }
296
+
297
+ ;; test callsite overwrite of unknown operand bundle
298
+ define void @test10 (i8* %p ) {
299
+ ; CHECK-LABEL: Function: test10
300
+ entry:
301
+ %q = getelementptr i8 , i8* %p , i64 16
302
+ call void @a_readonly_func (i8* %p ) #6 [ "unknown" () ]
303
+ call void @an_inaccessiblememonly_func () #7 [ "unknown" () ]
304
+ call void @an_inaccessibleorargmemonly_func (i8* %q ) #8 [ "unknown" () ]
305
+ call void @an_argmemonly_func (i8* %q ) #9 [ "unknown" () ]
306
+ ret void
307
+
308
+ ; CHECK: Just Ref: Ptr: i8* %p <-> call void @a_readonly_func(i8* %p) #6 [ "unknown"() ]
309
+ ; CHECK: Just Ref: Ptr: i8* %q <-> call void @a_readonly_func(i8* %p) #6 [ "unknown"() ]
310
+ ; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessiblememonly_func() #7 [ "unknown"() ]
311
+ ; CHECK: NoModRef: Ptr: i8* %q <-> call void @an_inaccessiblememonly_func() #7 [ "unknown"() ]
312
+ ; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #8 [ "unknown"() ]
313
+ ; CHECK: Both ModRef: Ptr: i8* %q <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #8 [ "unknown"() ]
314
+ ; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q) #9 [ "unknown"() ]
315
+ ; CHECK: Both ModRef: Ptr: i8* %q <-> call void @an_argmemonly_func(i8* %q) #9 [ "unknown"() ]
316
+ ; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #6 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #7 [ "unknown"() ]
317
+ ; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #6 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #8 [ "unknown"() ]
318
+ ; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #6 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #9 [ "unknown"() ]
319
+ ; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() #7 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #6 [ "unknown"() ]
320
+ ; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() #7 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #8 [ "unknown"() ]
321
+ ; CHECK: NoModRef: call void @an_inaccessiblememonly_func() #7 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #9 [ "unknown"() ]
322
+ ; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) #8 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #6 [ "unknown"() ]
323
+ ; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) #8 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #7 [ "unknown"() ]
324
+ ; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) #8 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #9 [ "unknown"() ]
325
+ ; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) #9 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #6 [ "unknown"() ]
326
+ ; CHECK: NoModRef: call void @an_argmemonly_func(i8* %q) #9 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #7 [ "unknown"() ]
327
+ ; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) #9 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #8 [ "unknown"() ]
328
+ }
329
+
330
+ attributes #0 = { argmemonly nounwind }
331
+ attributes #1 = { noinline nounwind readonly }
332
+ attributes #2 = { noinline nounwind writeonly }
333
+ attributes #3 = { nounwind ssp }
334
+ attributes #4 = { inaccessiblememonly nounwind }
335
+ attributes #5 = { inaccessiblemem_or_argmemonly nounwind }
336
+ attributes #6 = { readonly }
337
+ attributes #7 = { inaccessiblememonly }
338
+ attributes #8 = { inaccessiblemem_or_argmemonly }
339
+ attributes #9 = { argmemonly }
0 commit comments