xref: /llvm-project/mlir/test/Dialect/LLVMIR/inlining-alias-scopes.mlir (revision bf68e9047f62c22ca87f9a4a7c59a46b3de06abb)
1// RUN: mlir-opt %s -inline -split-input-file | FileCheck %s
2
3#alias_scope_domain = #llvm.alias_scope_domain<id = distinct[0]<>, description = "foo">
4#alias_scope = #llvm.alias_scope<id = distinct[1]<>, domain = #alias_scope_domain, description = "foo load">
5#alias_scope1 = #llvm.alias_scope<id = distinct[2]<>, domain = #alias_scope_domain, description = "foo store">
6
7// CHECK-DAG: #[[FOO_DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
8// CHECK-DAG: #[[$FOO_LOAD:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[FOO_DOMAIN]], description = {{.*}}>
9// CHECK-DAG: #[[$FOO_STORE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[FOO_DOMAIN]], description = {{.*}}>
10
11// CHECK-DAG: #[[BAR_DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
12// CHECK-DAG: #[[$BAR_LOAD:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[BAR_DOMAIN]], description = {{.*}}>
13// CHECK-DAG: #[[$BAR_STORE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[BAR_DOMAIN]], description = {{.*}}>
14
15// CHECK-LABEL: llvm.func @foo
16// CHECK: llvm.intr.experimental.noalias.scope.decl #[[$FOO_LOAD]]
17// CHECK: llvm.load
18// CHECK-SAME: alias_scopes = [#[[$FOO_LOAD]]]
19// CHECK-SAME: noalias_scopes = [#[[$FOO_STORE]]]
20// CHECK: llvm.store
21// CHECK-SAME: alias_scopes = [#[[$FOO_STORE]]]
22// CHECK-SAME: noalias_scopes = [#[[$FOO_LOAD]]]
23llvm.func @foo(%arg0: !llvm.ptr, %arg1: !llvm.ptr) {
24  %0 = llvm.mlir.constant(5 : i64) : i64
25  llvm.intr.experimental.noalias.scope.decl #alias_scope
26  %2 = llvm.load %arg1 {alias_scopes = [#alias_scope], alignment = 4 : i64, noalias_scopes = [#alias_scope1]} : !llvm.ptr -> f32
27  "test.one_region_op"() ({
28    %3 = llvm.getelementptr inbounds %arg0[%0] : (!llvm.ptr, i64) -> !llvm.ptr, f32
29    llvm.store %2, %3 {alias_scopes = [#alias_scope1], alignment = 4 : i64, noalias_scopes = [#alias_scope]} : f32, !llvm.ptr
30    "test.terminator"() : () -> ()
31  }) : () -> ()
32  llvm.return
33}
34
35// CHECK-LABEL: llvm.func @clone_alias_scopes
36// CHECK: llvm.intr.experimental.noalias.scope.decl #[[$BAR_LOAD]]
37// CHECK: llvm.load
38// CHECK-SAME: alias_scopes = [#[[$BAR_LOAD]]]
39// CHECK-SAME: noalias_scopes = [#[[$BAR_STORE]]]
40// CHECK: llvm.store
41// CHECK-SAME: alias_scopes = [#[[$BAR_STORE]]]
42// CHECK-SAME: noalias_scopes = [#[[$BAR_LOAD]]]
43llvm.func @clone_alias_scopes(%arg0: !llvm.ptr, %arg1: !llvm.ptr) {
44  llvm.call @foo(%arg0, %arg1) : (!llvm.ptr, !llvm.ptr) -> ()
45  llvm.return
46}
47
48// -----
49
50#alias_scope_domain = #llvm.alias_scope_domain<id = distinct[0]<>, description = "hello2">
51#alias_scope_domain1 = #llvm.alias_scope_domain<id = distinct[1]<>, description = "hello">
52#alias_scope = #llvm.alias_scope<id = distinct[2]<>, domain = #alias_scope_domain, description = "hello2: %a">
53#alias_scope1 = #llvm.alias_scope<id = distinct[3]<>, domain = #alias_scope_domain, description = "hello2: %b">
54#alias_scope2 = #llvm.alias_scope<id = distinct[4]<>, domain = #alias_scope_domain1, description = "hello: %a">
55
56// CHECK-DAG: #[[WITH_DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
57// CHECK-DAG: #[[$WITH_DOMAIN_SCOPE1:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[WITH_DOMAIN]], description = {{.*}}>
58// CHECK-DAG: #[[$WITH_DOMAIN_SCOPE2:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[WITH_DOMAIN]], description = {{.*}}>
59
60// CHECK-DAG: #[[CALL_DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
61// CHECK-DAG: #[[$CALL_DOMAIN_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[CALL_DOMAIN]], description = {{.*}}>
62
63// CHECK-DAG: #[[WITH_DOMAIN_NO_ALIAS:.*]] = #llvm.alias_scope_domain<{{.*}}>
64// CHECK-DAG: #[[$WITH_DOMAIN_NO_ALIAS_SCOPE1:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[WITH_DOMAIN_NO_ALIAS]], description = {{.*}}>
65// CHECK-DAG: #[[$WITH_DOMAIN_NO_ALIAS_SCOPE2:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[WITH_DOMAIN_NO_ALIAS]], description = {{.*}}>
66
67// CHECK-DAG: #[[WITH_DOMAIN_ALIAS:.*]] = #llvm.alias_scope_domain<{{.*}}>
68// CHECK-DAG: #[[$WITH_DOMAIN_ALIAS_SCOPE1:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[WITH_DOMAIN_ALIAS]], description = {{.*}}>
69// CHECK-DAG: #[[$WITH_DOMAIN_ALIAS_SCOPE2:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[WITH_DOMAIN_ALIAS]], description = {{.*}}>
70
71// CHECK-LABEL: llvm.func @callee_with_metadata(
72// CHECK: llvm.load
73// CHECK-SAME: noalias_scopes = [#[[$WITH_DOMAIN_SCOPE1]], #[[$WITH_DOMAIN_SCOPE2]]]
74// CHECK: llvm.store
75// CHECK-SAME: alias_scopes = [#[[$WITH_DOMAIN_SCOPE1]]]
76// CHECK-SAME: noalias_scopes = [#[[$WITH_DOMAIN_SCOPE2]]]
77// CHECK: llvm.store
78// CHECK-SAME: alias_scopes = [#[[$WITH_DOMAIN_SCOPE2]]]
79// CHECK-SAME: noalias_scopes = [#[[$WITH_DOMAIN_SCOPE1]]]
80// CHECK: llvm.load
81// CHECK-NOT: {{(no)?}}alias_scopes =
82// CHECK: llvm.store
83// CHECK-NOT: {{(no)?}}alias_scopes =
84llvm.func @callee_with_metadata(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
85  %0 = llvm.mlir.constant(5 : i64) : i64
86  %1 = llvm.mlir.constant(8 : i64) : i64
87  %2 = llvm.mlir.constant(7 : i64) : i64
88  %3 = llvm.load %arg2 {alignment = 4 : i64, noalias_scopes = [#alias_scope, #alias_scope1]} : !llvm.ptr -> f32
89  %4 = llvm.getelementptr inbounds %arg0[%0] : (!llvm.ptr, i64) -> !llvm.ptr, f32
90  llvm.store %3, %4 {alias_scopes = [#alias_scope], alignment = 4 : i64, noalias_scopes = [#alias_scope1]} : f32, !llvm.ptr
91  %5 = llvm.getelementptr inbounds %arg1[%1] : (!llvm.ptr, i64) -> !llvm.ptr, f32
92  llvm.store %3, %5 {alias_scopes = [#alias_scope1], alignment = 4 : i64, noalias_scopes = [#alias_scope]} : f32, !llvm.ptr
93  "test.one_region_op"() ({
94    %6 = llvm.load %arg2 {alignment = 4 : i64} : !llvm.ptr -> f32
95    %7 = llvm.getelementptr inbounds %arg0[%2] : (!llvm.ptr, i64) -> !llvm.ptr, f32
96    llvm.store %6, %7 {alignment = 4 : i64} : f32, !llvm.ptr
97    "test.terminator"() : () -> ()
98  }) : () -> ()
99  llvm.return
100}
101
102// CHECK-LABEL: llvm.func @callee_without_metadata(
103// CHECK-NOT: {{(no)?}}alias_scopes =
104
105llvm.func @callee_without_metadata(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
106  %0 = llvm.mlir.constant(5 : i64) : i64
107  %1 = llvm.mlir.constant(8 : i64) : i64
108  %2 = llvm.mlir.constant(7 : i64) : i64
109  %3 = llvm.load %arg2 {alignment = 4 : i64} : !llvm.ptr -> f32
110  %4 = llvm.getelementptr inbounds %arg0[%0] : (!llvm.ptr, i64) -> !llvm.ptr, f32
111  llvm.store %3, %4 {alignment = 4 : i64} : f32, !llvm.ptr
112  %5 = llvm.getelementptr inbounds %arg1[%1] : (!llvm.ptr, i64) -> !llvm.ptr, f32
113  llvm.store %3, %5 {alignment = 4 : i64} : f32, !llvm.ptr
114  "test.one_region_op"() ({
115    %6 = llvm.load %arg2 {alignment = 4 : i64} : !llvm.ptr -> f32
116    %7 = llvm.getelementptr inbounds %arg0[%2] : (!llvm.ptr, i64) -> !llvm.ptr, f32
117    llvm.store %6, %7 {alignment = 4 : i64} : f32, !llvm.ptr
118    "test.terminator"() : () -> ()
119  }) : () -> ()
120
121  llvm.return
122}
123
124// CHECK-LABEL: llvm.func @caller(
125// CHECK: llvm.load
126// CHECK-SAME: alias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
127// CHECK-NOT: noalias_scopes
128
129// Inlining @callee_with_metadata with noalias_scopes.
130
131// CHECK: llvm.load
132// CHECK-SAME: noalias_scopes = [#[[$WITH_DOMAIN_NO_ALIAS_SCOPE1]], #[[$WITH_DOMAIN_NO_ALIAS_SCOPE2]], #[[$CALL_DOMAIN_SCOPE]]]
133// CHECK: llvm.store
134// CHECK-SAME: alias_scopes = [#[[$WITH_DOMAIN_NO_ALIAS_SCOPE1]]]
135// CHECK-SAME: noalias_scopes = [#[[$WITH_DOMAIN_NO_ALIAS_SCOPE2]], #[[$CALL_DOMAIN_SCOPE]]]
136// CHECK: llvm.store
137// CHECK-SAME: alias_scopes = [#[[$WITH_DOMAIN_NO_ALIAS_SCOPE2]]]
138// CHECK-SAME: noalias_scopes = [#[[$WITH_DOMAIN_NO_ALIAS_SCOPE1]], #[[$CALL_DOMAIN_SCOPE]]]
139// CHECK: llvm.load
140// CHECK-NOT: alias_scopes
141// CHECK-SAME: noalias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
142// CHECK: llvm.store
143// CHECK-NOT: alias_scopes
144// CHECK-SAME: noalias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
145
146// Inlining @callee_with_metadata with alias_scopes.
147
148// CHECK: llvm.load
149// CHECK-SAME: alias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
150// CHECK-SAME: noalias_scopes = [#[[$WITH_DOMAIN_ALIAS_SCOPE1]], #[[$WITH_DOMAIN_ALIAS_SCOPE2]]]
151// CHECK: llvm.store
152// CHECK-SAME: alias_scopes = [#[[$WITH_DOMAIN_ALIAS_SCOPE1]], #[[$CALL_DOMAIN_SCOPE]]]
153// CHECK-SAME: noalias_scopes = [#[[$WITH_DOMAIN_ALIAS_SCOPE2]]]
154// CHECK: llvm.store
155// CHECK-SAME: alias_scopes = [#[[$WITH_DOMAIN_ALIAS_SCOPE2]], #[[$CALL_DOMAIN_SCOPE]]]
156// CHECK-SAME: noalias_scopes = [#[[$WITH_DOMAIN_ALIAS_SCOPE1]]]
157// CHECK: llvm.load
158// CHECK-SAME: alias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
159// CHECK-NOT: noalias_scopes
160// CHECK: llvm.store
161// CHECK-SAME: alias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
162// CHECK-NOT: noalias_scopes
163
164// Inlining @callee_without_metadata with noalias_scopes.
165
166// CHECK: llvm.load
167// CHECK-NOT: alias_scopes
168// CHECK-SAME: noalias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
169// CHECK: llvm.store
170// CHECK-NOT: alias_scopes
171// CHECK-SAME: noalias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
172// CHECK: llvm.store
173// CHECK-NOT: alias_scopes
174// CHECK-SAME: noalias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
175// CHECK: llvm.load
176// CHECK-NOT: alias_scopes
177// CHECK-SAME: noalias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
178// CHECK: llvm.store
179// CHECK-NOT: alias_scopes
180// CHECK-SAME: noalias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
181
182// Inlining @callee_without_metadata with alias_scopes.
183
184// CHECK: llvm.load
185// CHECK-SAME: alias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
186// CHECK-NOT: noalias_scopes
187// CHECK: llvm.store
188// CHECK-SAME: alias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
189// CHECK-NOT: noalias_scopes
190// CHECK: llvm.store
191// CHECK-SAME: alias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
192// CHECK-NOT: noalias_scopes
193// CHECK: llvm.load
194// CHECK-SAME: alias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
195// CHECK-NOT: noalias_scopes
196// CHECK: llvm.store
197// CHECK-SAME: alias_scopes = [#[[$CALL_DOMAIN_SCOPE]]]
198// CHECK-NOT: noalias_scopes
199
200llvm.func @caller(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
201  %0 = llvm.load %arg2 {alias_scopes = [#alias_scope2], alignment = 8 : i64} : !llvm.ptr -> !llvm.ptr
202  llvm.call @callee_with_metadata(%arg0, %arg1, %0) {noalias_scopes = [#alias_scope2]} : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
203  llvm.call @callee_with_metadata(%arg1, %arg1, %arg0) {alias_scopes = [#alias_scope2]} : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
204  llvm.call @callee_without_metadata(%arg0, %arg1, %0) {noalias_scopes = [#alias_scope2]} : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
205  llvm.call @callee_without_metadata(%arg1, %arg1, %arg0) {alias_scopes = [#alias_scope2]} : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
206  llvm.return
207}
208
209// -----
210
211// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
212// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
213// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
214
215llvm.func @foo(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr {llvm.noalias}) {
216  %0 = llvm.mlir.constant(5 : i64) : i64
217  %1 = llvm.load %arg1 {alignment = 4 : i64} : !llvm.ptr -> f32
218  %2 = llvm.getelementptr inbounds %arg0[%0] : (!llvm.ptr, i64) -> !llvm.ptr, f32
219  llvm.store %1, %2 {alignment = 4 : i64} : f32, !llvm.ptr
220  llvm.return
221}
222
223// CHECK-LABEL: llvm.func @bar
224// CHECK: llvm.load
225// CHECK-SAME: alias_scopes = [#[[$ARG1_SCOPE]]]
226// CHECK-SAME: noalias_scopes = [#[[$ARG0_SCOPE]]]
227// CHECK: llvm.store
228// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]]]
229// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
230llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
231  llvm.call @foo(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
232  llvm.return
233}
234
235// -----
236
237// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
238// CHECK-DAG: #[[$ARG_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
239
240llvm.func @foo(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr) {
241  %0 = llvm.mlir.constant(5 : i64) : i64
242  %1 = llvm.load %arg0 {alignment = 4 : i64} : !llvm.ptr -> f32
243  %2 = llvm.getelementptr inbounds %arg1[%0] : (!llvm.ptr, i64) -> !llvm.ptr, f32
244  llvm.store %1, %2 {alignment = 4 : i64} : f32, !llvm.ptr
245  llvm.return
246}
247
248// CHECK-LABEL: llvm.func @missing_noalias_on_one_ptr
249// CHECK: llvm.load
250// CHECK-SAME: alias_scopes = [#[[$ARG_SCOPE]]]
251// CHECK: llvm.store
252// CHECK-SAME: noalias_scopes = [#[[$ARG_SCOPE]]]
253llvm.func @missing_noalias_on_one_ptr(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
254  llvm.call @foo(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
255  llvm.return
256}
257
258// -----
259
260// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
261// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
262// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
263
264llvm.func @might_return_arg_derived(!llvm.ptr) -> !llvm.ptr
265
266llvm.func @foo(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr {llvm.noalias}) {
267  %0 = llvm.mlir.constant(5 : i64) : i32
268  %1 = llvm.call @might_return_arg_derived(%arg0) : (!llvm.ptr) -> !llvm.ptr
269  llvm.store %0, %1 : i32, !llvm.ptr
270  llvm.return
271}
272
273// CHECK-LABEL: llvm.func @bar
274// CHECK: llvm.call
275// CHECK-NOT: alias_scopes
276// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
277// CHECK: llvm.store
278// CHECK-NOT: alias_scopes
279// CHECK-NOT: noalias_scopes
280llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
281  llvm.call @foo(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
282  llvm.return
283}
284
285// -----
286
287// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
288// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
289// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
290
291llvm.func @random() -> i1
292
293llvm.func @block_arg(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr {llvm.noalias}) {
294  %0 = llvm.mlir.constant(5 : i64) : i32
295  %1 = llvm.call @random() : () -> i1
296  llvm.cond_br %1, ^bb0(%arg0 : !llvm.ptr), ^bb0(%arg1 : !llvm.ptr)
297
298^bb0(%arg2: !llvm.ptr):
299  llvm.store %0, %arg2 : i32, !llvm.ptr
300  llvm.return
301}
302
303// CHECK-LABEL: llvm.func @bar
304// CHECK: llvm.call
305// CHECK-NOT: alias_scopes
306// CHECK-SAME: noalias_scopes = [#[[$ARG0_SCOPE]], #[[$ARG1_SCOPE]]]
307// CHECK: llvm.store
308// CHECK: alias_scopes = [#[[$ARG0_SCOPE]], #[[$ARG1_SCOPE]]]
309llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
310  llvm.call @block_arg(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
311  llvm.return
312}
313
314// -----
315
316// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
317// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
318// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
319
320llvm.func @random() -> i1
321
322llvm.func @region_branch(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr {llvm.noalias}) {
323  %0 = llvm.mlir.constant(5 : i64) : i32
324  test.region_if %arg0: !llvm.ptr -> !llvm.ptr then {
325  ^bb0(%arg2: !llvm.ptr):
326    test.region_if_yield %arg0 : !llvm.ptr
327  } else {
328  ^bb0(%arg2: !llvm.ptr):
329    test.region_if_yield %arg0 : !llvm.ptr
330  } join {
331  ^bb0(%arg2: !llvm.ptr):
332    llvm.store %0, %arg2 : i32, !llvm.ptr
333    test.region_if_yield %arg0 : !llvm.ptr
334  }
335  llvm.return
336}
337
338// CHECK-LABEL: llvm.func @region_branch_inlining
339// CHECK: llvm.store
340// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]]]
341// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
342llvm.func @region_branch_inlining(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
343  llvm.call @region_branch(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
344  llvm.return
345}
346
347// -----
348
349llvm.func @missing_region_branch(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr {llvm.noalias}) {
350  %0 = llvm.mlir.constant(5 : i64) : i32
351  "test.one_region_op"() ({
352  ^bb0(%arg2: !llvm.ptr):
353    llvm.store %0, %arg2 : i32, !llvm.ptr
354    "test.terminator"() : () -> ()
355  }) : () -> ()
356  llvm.return
357}
358
359// CHECK-LABEL: llvm.func @missing_region_branch_inlining
360// CHECK: llvm.store
361// CHECK-NOT: alias_scopes
362// CHECK-NOT: noalias_scopes
363llvm.func @missing_region_branch_inlining(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
364  llvm.call @missing_region_branch(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
365  llvm.return
366}
367
368// -----
369
370// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
371// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
372// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
373
374llvm.func @random() -> i1
375
376llvm.func @block_arg(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr {llvm.noalias}) {
377  %0 = llvm.mlir.constant(5 : i64) : i32
378  %1 = llvm.mlir.constant(1 : i64) : i64
379  %2 = llvm.alloca %1 x i32 : (i64) -> !llvm.ptr
380  %3 = llvm.call @random() : () -> i1
381  llvm.cond_br %3, ^bb0(%arg0 : !llvm.ptr), ^bb0(%2 : !llvm.ptr)
382
383^bb0(%arg2: !llvm.ptr):
384  llvm.store %0, %arg2 : i32, !llvm.ptr
385  llvm.return
386}
387
388// CHECK-LABEL: llvm.func @bar
389// CHECK: llvm.call
390// CHECK-NOT: alias_scopes
391// CHECK-SAME: noalias_scopes = [#[[$ARG0_SCOPE]], #[[$ARG1_SCOPE]]]
392// CHECK: llvm.store
393// CHECK-NOT: alias_scopes
394// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
395llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
396  llvm.call @block_arg(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
397  llvm.return
398}
399
400// -----
401
402// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
403// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
404// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
405
406llvm.func @unknown() -> !llvm.ptr
407llvm.func @random() -> i1
408
409llvm.func @unknown_object(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr {llvm.noalias}) {
410  %0 = llvm.mlir.constant(5 : i64) : i32
411  %1 = llvm.call @random() : () -> i1
412  %2 = llvm.call @unknown() : () -> !llvm.ptr
413  llvm.cond_br %1, ^bb0(%arg0 : !llvm.ptr), ^bb0(%2 : !llvm.ptr)
414
415^bb0(%arg2: !llvm.ptr):
416  llvm.store %0, %arg2 : i32, !llvm.ptr
417  llvm.return
418}
419
420// CHECK-LABEL: llvm.func @bar
421// CHECK: llvm.call
422// CHECK-NOT: alias_scopes
423// CHECK-SAME: noalias_scopes = [#[[$ARG0_SCOPE]], #[[$ARG1_SCOPE]]]
424// CHECK: llvm.call
425// CHECK-NOT: alias_scopes
426// CHECK-SAME: noalias_scopes = [#[[$ARG0_SCOPE]], #[[$ARG1_SCOPE]]]
427// CHECK: llvm.store
428// CHECK-NOT: alias_scopes
429// CHECK-NOT: noalias_scopes
430llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
431  llvm.call @unknown_object(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
432  llvm.return
433}
434
435// -----
436
437// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
438// CHECK-DAG: #[[$ARG0_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
439// CHECK-DAG: #[[$ARG1_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
440
441llvm.func @supported_operations(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr {llvm.noalias}) {
442  %0 = llvm.mlir.constant(5 : i64) : i32
443  llvm.store %0, %arg1 : i32, !llvm.ptr
444  %1 = llvm.load %arg1 : !llvm.ptr -> i32
445  "llvm.intr.memcpy"(%arg0, %arg1, %1) <{ isVolatile = false }> : (!llvm.ptr, !llvm.ptr, i32) -> ()
446  "llvm.intr.memmove"(%arg0, %arg1, %1) <{ isVolatile = false }> : (!llvm.ptr, !llvm.ptr, i32) -> ()
447  "llvm.intr.memcpy.inline"(%arg0, %arg1) <{ isVolatile = false, len = 4 : i32}> : (!llvm.ptr, !llvm.ptr) -> ()
448  %2 = llvm.trunc %0 : i32 to i8
449  "llvm.intr.memset"(%arg0, %2, %1) <{ isVolatile = false}> : (!llvm.ptr, i8, i32) -> ()
450  %3 = llvm.cmpxchg %arg0, %0, %1 seq_cst seq_cst : !llvm.ptr, i32
451  %4 = llvm.atomicrmw add %arg0, %0 seq_cst : !llvm.ptr, i32
452  llvm.return
453}
454
455// CHECK-LABEL: llvm.func @bar
456// CHECK: llvm.store
457// CHECK-SAME: alias_scopes = [#[[$ARG1_SCOPE]]]
458// CHECK-SAME: noalias_scopes = [#[[$ARG0_SCOPE]]]
459// CHECK: llvm.load
460// CHECK-SAME: alias_scopes = [#[[$ARG1_SCOPE]]]
461// CHECK-SAME: noalias_scopes = [#[[$ARG0_SCOPE]]]
462// CHECK: "llvm.intr.memcpy"
463// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]], #[[$ARG1_SCOPE]]]
464// CHECK-NOT: noalias_scopes
465// CHECK: "llvm.intr.memmove"
466// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]], #[[$ARG1_SCOPE]]]
467// CHECK-NOT: noalias_scopes
468// CHECK: "llvm.intr.memcpy.inline"
469// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]], #[[$ARG1_SCOPE]]]
470// CHECK-NOT: noalias_scopes
471// CHECK: "llvm.intr.memset"
472// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]]]
473// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
474// CHECK: llvm.cmpxchg
475// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]]]
476// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
477// CHECK: llvm.atomicrmw
478// CHECK-SAME: alias_scopes = [#[[$ARG0_SCOPE]]]
479// CHECK-SAME: noalias_scopes = [#[[$ARG1_SCOPE]]]
480llvm.func @bar(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) {
481  llvm.call @supported_operations(%arg0, %arg2) : (!llvm.ptr, !llvm.ptr) -> ()
482  llvm.return
483}
484
485// -----
486
487// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
488// CHECK-DAG: #[[$ARG_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
489
490llvm.func @foo(%arg: i32)
491
492llvm.func @region(%arg0: !llvm.ptr {llvm.noalias}) {
493  "test.one_region_op"() ({
494    %1 = llvm.load %arg0 : !llvm.ptr -> i32
495    llvm.call @foo(%1) : (i32) -> ()
496    "test.terminator"() : () -> ()
497  }) : () -> ()
498  llvm.return
499}
500
501// CHECK-LABEL: llvm.func @noalias_with_region
502// CHECK: llvm.load
503// CHECK-SAME: alias_scopes = [#[[$ARG_SCOPE]]]
504// CHECK: llvm.call
505// CHECK-NOT: alias_scopes
506// CHECK-SAME: noalias_scopes = [#[[$ARG_SCOPE]]]
507llvm.func @noalias_with_region(%arg0: !llvm.ptr) {
508  llvm.call @region(%arg0) : (!llvm.ptr) -> ()
509  llvm.return
510}
511
512// -----
513
514// CHECK-DAG: #[[DOMAIN:.*]] = #llvm.alias_scope_domain<{{.*}}>
515// CHECK-DAG: #[[$ARG_SCOPE:.*]] = #llvm.alias_scope<id = {{.*}}, domain = #[[DOMAIN]]{{(,.*)?}}>
516
517llvm.func @foo(%arg: i32)
518
519llvm.func @func(%arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr) {
520  %cond = llvm.load %arg1 : !llvm.ptr -> i1
521  %1 = llvm.getelementptr inbounds %arg0[1] : (!llvm.ptr) -> !llvm.ptr, f32
522  %selected = llvm.select %cond, %arg0, %1 : i1, !llvm.ptr
523  %2 = llvm.load %selected : !llvm.ptr -> i32
524  llvm.call @foo(%2) : (i32) -> ()
525  llvm.return
526}
527
528// CHECK-LABEL: llvm.func @selects
529// CHECK: llvm.load
530// CHECK-NOT: alias_scopes
531// CHECK-SAME: noalias_scopes = [#[[$ARG_SCOPE]]]
532// CHECK: llvm.load
533// CHECK-SAME: alias_scopes = [#[[$ARG_SCOPE]]]
534llvm.func @selects(%arg0: !llvm.ptr, %arg1: !llvm.ptr) {
535  llvm.call @func(%arg0, %arg1) : (!llvm.ptr, !llvm.ptr) -> ()
536  llvm.return
537}
538
539// -----
540
541llvm.func @foo(%arg: i32)
542
543llvm.func @func(%cond: i1, %arg0: !llvm.ptr {llvm.noalias}, %arg1: !llvm.ptr) {
544  %selected = llvm.select %cond, %arg0, %arg1 : i1, !llvm.ptr
545  %2 = llvm.load %selected : !llvm.ptr -> i32
546  llvm.call @foo(%2) : (i32) -> ()
547  llvm.return
548}
549
550// CHECK-LABEL: llvm.func @multi_ptr_select
551// CHECK: llvm.load
552// CHECK-NOT: alias_scopes
553// CHECK-NOT: noalias_scopes
554// CHECK: llvm.call @foo
555llvm.func @multi_ptr_select(%cond: i1, %arg0: !llvm.ptr, %arg1: !llvm.ptr) {
556  llvm.call @func(%cond, %arg0, %arg1) : (i1, !llvm.ptr, !llvm.ptr) -> ()
557  llvm.return
558}
559