xref: /llvm-project/llvm/test/Analysis/BasicAA/cs-cs.ll (revision ef1722497b29370046a279b8de697d9384c04bbf)
1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
2target 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"
3target triple = "arm-apple-ios"
4
5declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1) #0
6declare void @llvm.memcpy.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1) #0
7declare void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i32) #0
8
9declare void @a_readonly_func(ptr) #1
10declare void @a_writeonly_func(ptr) #2
11
12define void @test2(ptr %P, ptr %Q) #3 {
13  load i8, ptr %P
14  load i8, ptr %Q
15  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
16  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
17  ret void
18
19; CHECK-LABEL: Function: test2:
20
21; CHECK:   MayAlias:     i8* %P, i8* %Q
22; CHECK:   Both ModRef:  Ptr: i8* %P     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
23; CHECK:   Both ModRef:  Ptr: i8* %Q     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
24; CHECK:   Both ModRef:  Ptr: i8* %P     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
25; CHECK:   Both ModRef:  Ptr: i8* %Q     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
26; CHECK:   Both ModRef:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
27; CHECK:   Both ModRef:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
28}
29
30define void @test2_atomic(ptr %P, ptr %Q) #3 {
31  load i8, ptr %P
32  load i8, ptr %Q
33  tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
34  tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
35  ret void
36
37; CHECK-LABEL: Function: test2_atomic:
38
39; CHECK:   MayAlias:     i8* %P, i8* %Q
40; CHECK:   Both ModRef:  Ptr: i8* %P     <->  tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
41; CHECK:   Both ModRef:  Ptr: i8* %Q     <->  tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
42; CHECK:   Both ModRef:  Ptr: i8* %P     <->  tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
43; CHECK:   Both ModRef:  Ptr: i8* %Q     <->  tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
44; CHECK:   Both ModRef:   tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1) <->   tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
45; CHECK:   Both ModRef:   tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1) <->   tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
46}
47
48define void @test2a(ptr noalias %P, ptr noalias %Q) #3 {
49  load i8, ptr %P
50  load i8, ptr %Q
51  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
52  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
53  ret void
54
55; CHECK-LABEL: Function: test2a:
56
57; CHECK: NoAlias:      i8* %P, i8* %Q
58; CHECK: Just Mod:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
59; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
60; CHECK: Just Mod:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
61; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
62; CHECK: Just Mod:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
63; CHECK: Just Mod:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
64}
65
66define void @test2b(ptr noalias %P, ptr noalias %Q) #3 {
67  load i8, ptr %P
68  load i8, ptr %Q
69  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
70  %R = getelementptr i8, ptr %P, i64 12
71  load i8, ptr %R
72  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
73  ret void
74
75; CHECK-LABEL: Function: test2b:
76
77; CHECK: NoAlias:      i8* %P, i8* %Q
78; CHECK: NoAlias:      i8* %P, i8* %R
79; CHECK: NoAlias:      i8* %Q, i8* %R
80; CHECK: Just Mod:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
81; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
82; CHECK: NoModRef:  Ptr: i8* %R        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
83; CHECK: NoModRef:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
84; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
85; CHECK: Just Mod:  Ptr: i8* %R        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
86; CHECK: NoModRef:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
87; CHECK: NoModRef:   tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
88}
89
90define void @test2c(ptr noalias %P, ptr noalias %Q) #3 {
91  load i8, ptr %P
92  load i8, ptr %Q
93  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
94  %R = getelementptr i8, ptr %P, i64 11
95  load i8, ptr %R
96  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
97  ret void
98
99; CHECK-LABEL: Function: test2c:
100
101; CHECK: NoAlias:      i8* %P, i8* %Q
102; CHECK: NoAlias:      i8* %P, i8* %R
103; CHECK: NoAlias:      i8* %Q, i8* %R
104; CHECK: Just Mod:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
105; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
106; CHECK: Just Mod:  Ptr: i8* %R        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
107; CHECK: NoModRef:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
108; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
109; CHECK: Just Mod:  Ptr: i8* %R        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
110; CHECK: Just Mod:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
111; CHECK: Just Mod:   tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
112}
113
114define void @test2d(ptr noalias %P, ptr noalias %Q) #3 {
115  load i8, ptr %P
116  load i8, ptr %Q
117  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
118  %R = getelementptr i8, ptr %P, i64 -12
119  load i8, ptr %R
120  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
121  ret void
122
123; CHECK-LABEL: Function: test2d:
124
125; CHECK: NoAlias:      i8* %P, i8* %Q
126; CHECK: NoAlias:      i8* %P, i8* %R
127; CHECK: NoAlias:      i8* %Q, i8* %R
128; CHECK: Just Mod:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
129; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
130; CHECK: NoModRef:  Ptr: i8* %R        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
131; CHECK: NoModRef:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
132; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
133; CHECK: Just Mod:  Ptr: i8* %R        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
134; CHECK: NoModRef:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
135; CHECK: NoModRef:   tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
136}
137
138define void @test2e(ptr noalias %P, ptr noalias %Q) #3 {
139  load i8, ptr %P
140  load i8, ptr %Q
141  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
142  %R = getelementptr i8, ptr %P, i64 -11
143  load i8, ptr %R
144  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
145  ret void
146
147; CHECK-LABEL: Function: test2e:
148
149; CHECK: NoAlias:      i8* %P, i8* %Q
150; CHECK: NoAlias:      i8* %P, i8* %R
151; CHECK: NoAlias:      i8* %Q, i8* %R
152; CHECK: Just Mod:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
153; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
154; CHECK: NoModRef:  Ptr: i8* %R        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
155; CHECK: Just Mod:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
156; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
157; CHECK: Just Mod:  Ptr: i8* %R        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
158; CHECK: Just Mod:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false)
159; CHECK: Just Mod:   tail call void @llvm.memcpy.p0.p0.i64(ptr %R, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
160}
161
162define void @test3(ptr %P, ptr %Q) #3 {
163  load i8, ptr %P
164  load i8, ptr %Q
165  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 8, i1 false)
166  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
167  ret void
168
169; CHECK-LABEL: Function: test3:
170
171; CHECK: MayAlias:     i8* %P, i8* %Q
172; CHECK: Both ModRef:  Ptr: i8* %P     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 8, i1 false)
173; CHECK: Both ModRef:  Ptr: i8* %Q     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 8, i1 false)
174; CHECK: Both ModRef:  Ptr: i8* %P     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
175; CHECK: Both ModRef:  Ptr: i8* %Q     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
176; CHECK: Both ModRef:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 8, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
177; CHECK: Both ModRef:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 8, i1 false)
178}
179
180define void @test3a(ptr noalias %P, ptr noalias %Q) #3 {
181  load i8, ptr %P
182  load i8, ptr %Q
183  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 8, i1 false)
184  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
185  ret void
186
187; CHECK-LABEL: Function: test3a:
188
189; CHECK: NoAlias:      i8* %P, i8* %Q
190; CHECK: Just Mod:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 8, i1 false)
191; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 8, i1 false)
192; CHECK: Just Mod:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
193; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
194; CHECK: Just Mod:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 8, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
195; CHECK: Just Mod:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 8, i1 false)
196}
197
198define void @test4(ptr %P, ptr noalias %Q) #3 {
199  load i8, ptr %P
200  load i8, ptr %Q
201  tail call void @llvm.memset.p0.i64(ptr %P, i8 42, i64 8, i1 false)
202  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
203  ret void
204
205; CHECK-LABEL: Function: test4:
206
207; CHECK: NoAlias:      i8* %P, i8* %Q
208; CHECK: Just Mod:  Ptr: i8* %P        <->  tail call void @llvm.memset.p0.i64(ptr %P, i8 42, i64 8, i1 false)
209; CHECK: NoModRef:  Ptr: i8* %Q        <->  tail call void @llvm.memset.p0.i64(ptr %P, i8 42, i64 8, i1 false)
210; CHECK: Just Mod:  Ptr: i8* %P        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
211; CHECK: Just Ref:  Ptr: i8* %Q        <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
212; CHECK: Just Mod:   tail call void @llvm.memset.p0.i64(ptr %P, i8 42, i64 8, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
213; CHECK: Just Mod:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memset.p0.i64(ptr %P, i8 42, i64 8, i1 false)
214}
215
216define void @test5(ptr %P, ptr %Q, ptr %R) #3 {
217  load i8, ptr %P
218  load i8, ptr %Q
219  load i8, ptr %R
220  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
221  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
222  ret void
223
224; CHECK-LABEL: Function: test5:
225
226; CHECK: MayAlias:     i8* %P, i8* %Q
227; CHECK: MayAlias:     i8* %P, i8* %R
228; CHECK: MayAlias:     i8* %Q, i8* %R
229; CHECK: Both ModRef:  Ptr: i8* %P     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
230; CHECK: Both ModRef:  Ptr: i8* %Q     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
231; CHECK: Both ModRef:  Ptr: i8* %R     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
232; CHECK: Both ModRef:  Ptr: i8* %P     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
233; CHECK: Both ModRef:  Ptr: i8* %Q     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
234; CHECK: Both ModRef:  Ptr: i8* %R     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
235; CHECK: Both ModRef:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
236; CHECK: Both ModRef:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
237}
238
239define void @test5a(ptr noalias %P, ptr noalias %Q, ptr noalias %R) nounwind ssp {
240  load i8, ptr %P
241  load i8, ptr %Q
242  load i8, ptr %R
243  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
244  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
245  ret void
246
247; CHECK-LABEL: Function: test5a:
248
249; CHECK: NoAlias:     i8* %P, i8* %Q
250; CHECK: NoAlias:     i8* %P, i8* %R
251; CHECK: NoAlias:     i8* %Q, i8* %R
252; CHECK: Just Mod:  Ptr: i8* %P     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
253; CHECK: Just Ref:  Ptr: i8* %Q     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
254; CHECK: NoModRef:  Ptr: i8* %R     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
255; CHECK: Just Mod:  Ptr: i8* %P     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
256; CHECK: NoModRef:  Ptr: i8* %Q     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
257; CHECK: Just Ref:  Ptr: i8* %R     <->  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
258; CHECK: Just Mod:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
259; CHECK: Just Mod:   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false) <->   tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
260}
261
262define void @test6(ptr %P) #3 {
263  load i8, ptr %P
264  call void @llvm.memset.p0.i64(ptr align 8 %P, i8 -51, i64 32, i1 false)
265  call void @a_readonly_func(ptr %P)
266  ret void
267
268; CHECK-LABEL: Function: test6:
269
270; CHECK: Just Mod:  Ptr: i8* %P        <->  call void @llvm.memset.p0.i64(ptr align 8 %P, i8 -51, i64 32, i1 false)
271; CHECK: Just Ref:  Ptr: i8* %P        <->  call void @a_readonly_func(ptr %P)
272; CHECK: Just Mod:   call void @llvm.memset.p0.i64(ptr align 8 %P, i8 -51, i64 32, i1 false) <->   call void @a_readonly_func(ptr %P)
273; CHECK: Just Ref:   call void @a_readonly_func(ptr %P) <->   call void @llvm.memset.p0.i64(ptr align 8 %P, i8 -51, i64 32, i1 false)
274}
275
276define void @test7(ptr %P) #3 {
277  load i8, ptr %P
278  call void @a_writeonly_func(ptr %P)
279  call void @a_readonly_func(ptr %P)
280  ret void
281
282; CHECK-LABEL: Function: test7:
283
284; CHECK: Just Mod:  Ptr: i8* %P        <->  call void @a_writeonly_func(ptr %P)
285; CHECK: Just Ref:  Ptr: i8* %P        <->  call void @a_readonly_func(ptr %P)
286; CHECK: Just Mod:   call void @a_writeonly_func(ptr %P) <->   call void @a_readonly_func(ptr %P)
287; CHECK: Just Ref:   call void @a_readonly_func(ptr %P) <->   call void @a_writeonly_func(ptr %P)
288}
289
290declare void @an_inaccessiblememonly_func() #4
291declare void @an_inaccessibleorargmemonly_func(ptr) #5
292declare void @an_argmemonly_func(ptr) #0
293
294define void @test8(ptr %p) {
295entry:
296  %q = getelementptr i8, ptr %p, i64 16
297  load i8, ptr %p
298  load i8, ptr %q
299  call void @a_readonly_func(ptr %p)
300  call void @an_inaccessiblememonly_func()
301  call void @a_writeonly_func(ptr %q)
302  call void @an_inaccessiblememonly_func()
303  call void @an_inaccessibleorargmemonly_func(ptr %q)
304  call void @an_argmemonly_func(ptr %q)
305  ret void
306
307; CHECK-LABEL: Function: test8
308; CHECK: NoModRef:  Ptr: i8* %p <->  call void @an_inaccessiblememonly_func()
309; CHECK: NoModRef:  Ptr: i8* %q <->  call void @an_inaccessiblememonly_func()
310; CHECK: Both ModRef:  Ptr: i8* %p <->  call void @an_inaccessibleorargmemonly_func(ptr %q)
311; CHECK: Both ModRef:  Ptr: i8* %q <->  call void @an_inaccessibleorargmemonly_func(ptr %q)
312; CHECK: Both ModRef:  Ptr: i8* %p <->  call void @an_argmemonly_func(ptr %q)
313; CHECK: Both ModRef:  Ptr: i8* %q <->  call void @an_argmemonly_func(ptr %q)
314; CHECK: Just Ref: call void @a_readonly_func(ptr %p) <-> call void @an_inaccessiblememonly_func()
315; CHECK: Just Ref: call void @a_readonly_func(ptr %p) <-> call void @an_inaccessibleorargmemonly_func(ptr %q)
316; CHECK: Just Ref: call void @a_readonly_func(ptr %p) <-> call void @an_argmemonly_func(ptr %q)
317; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @a_readonly_func(ptr %p)
318; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @a_writeonly_func(ptr %q)
319; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @an_inaccessiblememonly_func()
320; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @an_inaccessibleorargmemonly_func(ptr %q)
321; CHECK: NoModRef: call void @an_inaccessiblememonly_func() <-> call void @an_argmemonly_func(ptr %q)
322; CHECK: Just Mod: call void @a_writeonly_func(ptr %q) <-> call void @an_inaccessiblememonly_func()
323; CHECK: Just Mod: call void @a_writeonly_func(ptr %q) <-> call void @an_inaccessibleorargmemonly_func(ptr %q)
324; CHECK: Just Mod: call void @a_writeonly_func(ptr %q) <-> call void @an_argmemonly_func(ptr %q)
325; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(ptr %q) <-> call void @a_readonly_func(ptr %p)
326; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(ptr %q) <-> call void @a_writeonly_func(ptr %q)
327; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(ptr %q) <-> call void @an_inaccessiblememonly_func()
328; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(ptr %q) <-> call void @an_argmemonly_func(ptr %q)
329; CHECK: Both ModRef: call void @an_argmemonly_func(ptr %q) <-> call void @a_readonly_func(ptr %p)
330; CHECK: Both ModRef: call void @an_argmemonly_func(ptr %q) <-> call void @a_writeonly_func(ptr %q)
331; CHECK: NoModRef: call void @an_argmemonly_func(ptr %q) <-> call void @an_inaccessiblememonly_func()
332; CHECK: Both ModRef: call void @an_argmemonly_func(ptr %q) <-> call void @an_inaccessibleorargmemonly_func(ptr %q)
333}
334
335;; test that MustAlias is set for calls when no MayAlias is found.
336declare void @another_argmemonly_func(ptr, ptr) #0
337define void @test8a(ptr noalias %p, ptr noalias %q) {
338entry:
339  load i8, ptr %p
340  load i8, ptr %q
341  call void @another_argmemonly_func(ptr %p, ptr %q)
342  ret void
343
344; CHECK-LABEL: Function: test8a
345; CHECK: Both ModRef:  Ptr: i8* %p <->  call void @another_argmemonly_func(ptr %p, ptr %q)
346; CHECK: Both ModRef:  Ptr: i8* %q <->  call void @another_argmemonly_func(ptr %p, ptr %q)
347}
348define void @test8b(ptr %p, ptr %q) {
349entry:
350  load i8, ptr %p
351  load i8, ptr %q
352  call void @another_argmemonly_func(ptr %p, ptr %q)
353  ret void
354
355; CHECK-LABEL: Function: test8b
356; CHECK: Both ModRef:  Ptr: i8* %p <->  call void @another_argmemonly_func(ptr %p, ptr %q)
357; CHECK: Both ModRef:  Ptr: i8* %q <->  call void @another_argmemonly_func(ptr %p, ptr %q)
358}
359
360
361;; test that unknown operand bundle has unknown effect to the heap
362define void @test9(ptr %p) {
363; CHECK-LABEL: Function: test9
364entry:
365  %q = getelementptr i8, ptr %p, i64 16
366  load i8, ptr %p
367  load i8, ptr %q
368  call void @a_readonly_func(ptr %p) [ "unknown"() ]
369  call void @an_inaccessiblememonly_func() [ "unknown"() ]
370  call void @an_inaccessibleorargmemonly_func(ptr %q) [ "unknown"() ]
371  call void @an_argmemonly_func(ptr %q) [ "unknown"() ]
372  ret void
373
374; CHECK: Both ModRef:  Ptr: i8* %p     <->  call void @a_readonly_func(ptr %p) [ "unknown"() ]
375; CHECK: Both ModRef:  Ptr: i8* %q     <->  call void @a_readonly_func(ptr %p) [ "unknown"() ]
376; CHECK: Both ModRef:  Ptr: i8* %p     <->  call void @an_inaccessiblememonly_func() [ "unknown"() ]
377; CHECK: Both ModRef:  Ptr: i8* %q     <->  call void @an_inaccessiblememonly_func() [ "unknown"() ]
378; CHECK: Both ModRef:  Ptr: i8* %p     <->  call void @an_inaccessibleorargmemonly_func(ptr %q) [ "unknown"() ]
379; CHECK: Both ModRef:  Ptr: i8* %q     <->  call void @an_inaccessibleorargmemonly_func(ptr %q) [ "unknown"() ]
380; CHECK: Both ModRef:  Ptr: i8* %p     <->  call void @an_argmemonly_func(ptr %q) [ "unknown"() ]
381; CHECK: Both ModRef:  Ptr: i8* %q     <->  call void @an_argmemonly_func(ptr %q) [ "unknown"() ]
382; CHECK: Both ModRef:   call void @a_readonly_func(ptr %p) [ "unknown"() ] <->   call void @an_inaccessiblememonly_func() [ "unknown"() ]
383; CHECK: Both ModRef:   call void @a_readonly_func(ptr %p) [ "unknown"() ] <->   call void @an_inaccessibleorargmemonly_func(ptr %q) [ "unknown"() ]
384; CHECK: Both ModRef:   call void @a_readonly_func(ptr %p) [ "unknown"() ] <->   call void @an_argmemonly_func(ptr %q) [ "unknown"() ]
385; CHECK: Both ModRef:   call void @an_inaccessiblememonly_func() [ "unknown"() ] <->   call void @a_readonly_func(ptr %p) [ "unknown"() ]
386; CHECK: Both ModRef:   call void @an_inaccessiblememonly_func() [ "unknown"() ] <->   call void @an_inaccessibleorargmemonly_func(ptr %q) [ "unknown"() ]
387; CHECK: Both ModRef:   call void @an_inaccessiblememonly_func() [ "unknown"() ] <->   call void @an_argmemonly_func(ptr %q) [ "unknown"() ]
388; CHECK: Both ModRef:   call void @an_inaccessibleorargmemonly_func(ptr %q) [ "unknown"() ] <->   call void @a_readonly_func(ptr %p) [ "unknown"() ]
389; CHECK: Both ModRef:   call void @an_inaccessibleorargmemonly_func(ptr %q) [ "unknown"() ] <->   call void @an_inaccessiblememonly_func() [ "unknown"() ]
390; CHECK: Both ModRef:   call void @an_inaccessibleorargmemonly_func(ptr %q) [ "unknown"() ] <->   call void @an_argmemonly_func(ptr %q) [ "unknown"() ]
391; CHECK: Both ModRef:   call void @an_argmemonly_func(ptr %q) [ "unknown"() ] <->   call void @a_readonly_func(ptr %p) [ "unknown"() ]
392; CHECK: Both ModRef:   call void @an_argmemonly_func(ptr %q) [ "unknown"() ] <->   call void @an_inaccessiblememonly_func() [ "unknown"() ]
393; CHECK: Both ModRef:   call void @an_argmemonly_func(ptr %q) [ "unknown"() ] <->   call void @an_inaccessibleorargmemonly_func(ptr %q) [ "unknown"() ]
394}
395
396;; test callsite overwrite of unknown operand bundle
397define void @test10(ptr %p) {
398; CHECK-LABEL: Function: test10
399entry:
400  %q = getelementptr i8, ptr %p, i64 16
401  load i8, ptr %p
402  load i8, ptr %q
403  call void @a_readonly_func(ptr %p) #6 [ "unknown"() ]
404  call void @an_inaccessiblememonly_func() #7 [ "unknown"() ]
405  call void @an_inaccessibleorargmemonly_func(ptr %q) #8 [ "unknown"() ]
406  call void @an_argmemonly_func(ptr %q) #9 [ "unknown"() ]
407  ret void
408
409; CHECK: Just Ref:  Ptr: i8* %p        <->  call void @a_readonly_func(ptr %p) #9 [ "unknown"() ]
410; CHECK: Just Ref:  Ptr: i8* %q        <->  call void @a_readonly_func(ptr %p) #9 [ "unknown"() ]
411; CHECK: NoModRef:  Ptr: i8* %p        <->  call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
412; CHECK: NoModRef:  Ptr: i8* %q        <->  call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
413; CHECK: Both ModRef:  Ptr: i8* %p        <->  call void @an_inaccessibleorargmemonly_func(ptr %q) #11 [ "unknown"() ]
414; CHECK: Both ModRef:  Ptr: i8* %q     <->  call void @an_inaccessibleorargmemonly_func(ptr %q) #11 [ "unknown"() ]
415; CHECK: Both ModRef:  Ptr: i8* %p        <->  call void @an_argmemonly_func(ptr %q) #12 [ "unknown"() ]
416; CHECK: Both ModRef:  Ptr: i8* %q     <->  call void @an_argmemonly_func(ptr %q) #12 [ "unknown"() ]
417; CHECK: Just Ref:   call void @a_readonly_func(ptr %p) #9 [ "unknown"() ] <->   call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
418; CHECK: Just Ref:   call void @a_readonly_func(ptr %p) #9 [ "unknown"() ] <->   call void @an_inaccessibleorargmemonly_func(ptr %q) #11 [ "unknown"() ]
419; CHECK: Just Ref:   call void @a_readonly_func(ptr %p) #9 [ "unknown"() ] <->   call void @an_argmemonly_func(ptr %q) #12 [ "unknown"() ]
420; CHECK: Both ModRef:   call void @an_inaccessiblememonly_func() #10 [ "unknown"() ] <->   call void @a_readonly_func(ptr %p) #9 [ "unknown"() ]
421; CHECK: Both ModRef:   call void @an_inaccessiblememonly_func() #10 [ "unknown"() ] <->   call void @an_inaccessibleorargmemonly_func(ptr %q) #11 [ "unknown"() ]
422; CHECK: NoModRef:   call void @an_inaccessiblememonly_func() #10 [ "unknown"() ] <->   call void @an_argmemonly_func(ptr %q) #12 [ "unknown"() ]
423; CHECK: Both ModRef:   call void @an_inaccessibleorargmemonly_func(ptr %q) #11 [ "unknown"() ] <->   call void @a_readonly_func(ptr %p) #9 [ "unknown"() ]
424; CHECK: Both ModRef:   call void @an_inaccessibleorargmemonly_func(ptr %q) #11 [ "unknown"() ] <->   call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
425; CHECK: Both ModRef:   call void @an_inaccessibleorargmemonly_func(ptr %q) #11 [ "unknown"() ] <->   call void @an_argmemonly_func(ptr %q) #12 [ "unknown"() ]
426; CHECK: Both ModRef:   call void @an_argmemonly_func(ptr %q) #12 [ "unknown"() ] <->   call void @a_readonly_func(ptr %p) #9 [ "unknown"() ]
427; CHECK: NoModRef:   call void @an_argmemonly_func(ptr %q) #12 [ "unknown"() ] <->   call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
428; CHECK: Both ModRef:   call void @an_argmemonly_func(ptr %q) #12 [ "unknown"() ] <->   call void @an_inaccessibleorargmemonly_func(ptr %q) #11 [ "unknown"() ]
429}
430
431attributes #0 = { argmemonly nounwind }
432attributes #1 = { noinline nounwind readonly }
433attributes #2 = { noinline nounwind writeonly }
434attributes #3 = { nounwind ssp }
435attributes #4 = { inaccessiblememonly nounwind }
436attributes #5 = { inaccessiblemem_or_argmemonly nounwind }
437attributes #6 = { readonly }
438attributes #7 = { inaccessiblememonly }
439attributes #8 = { inaccessiblemem_or_argmemonly }
440attributes #9 = { argmemonly }
441