xref: /llvm-project/mlir/test/Analysis/test-alias-analysis.mlir (revision 13bd41096286305ee603428f6adf161f52981827)
1// RUN: mlir-opt %s -pass-pipeline='builtin.module(func.func(test-alias-analysis))' -split-input-file -allow-unregistered-dialect 2>&1 | FileCheck %s
2
3// CHECK-LABEL: Testing : "simple"
4// CHECK-DAG: func.region0#0 <-> func.region0#1: MayAlias
5
6// CHECK-DAG: alloca_1#0 <-> alloca_2#0: NoAlias
7// CHECK-DAG: alloca_1#0 <-> alloc_1#0: NoAlias
8// CHECK-DAG: alloca_1#0 <-> alloc_2#0: NoAlias
9// CHECK-DAG: alloca_1#0 <-> func.region0#0: NoAlias
10// CHECK-DAG: alloca_1#0 <-> func.region0#1: NoAlias
11
12// CHECK-DAG: alloca_2#0 <-> alloc_1#0: NoAlias
13// CHECK-DAG: alloca_2#0 <-> alloc_2#0: NoAlias
14// CHECK-DAG: alloca_2#0 <-> func.region0#0: NoAlias
15// CHECK-DAG: alloca_2#0 <-> func.region0#1: NoAlias
16
17// CHECK-DAG: alloc_1#0 <-> alloc_2#0: NoAlias
18// CHECK-DAG: alloc_1#0 <-> func.region0#0: NoAlias
19// CHECK-DAG: alloc_1#0 <-> func.region0#1: NoAlias
20
21// CHECK-DAG: alloc_2#0 <-> func.region0#0: NoAlias
22// CHECK-DAG: alloc_2#0 <-> func.region0#1: NoAlias
23func.func @simple(%arg: memref<2xf32>, %arg1: memref<2xf32>) attributes {test.ptr = "func"} {
24  %0 = memref.alloca() {test.ptr = "alloca_1"} : memref<8x64xf32>
25  %1 = memref.alloca() {test.ptr = "alloca_2"} : memref<8x64xf32>
26  %2 = memref.alloc() {test.ptr = "alloc_1"} : memref<8x64xf32>
27  %3 = memref.alloc() {test.ptr = "alloc_2"} : memref<8x64xf32>
28  return
29}
30
31// -----
32
33// CHECK-LABEL: Testing : "control_flow"
34// CHECK-DAG: alloca_1#0 <-> func.region0.block1#0: MustAlias
35// CHECK-DAG: alloca_1#0 <-> func.region0.block2#0: MustAlias
36
37// CHECK-DAG: alloca_2#0 <-> func.region0.block1#0: NoAlias
38// CHECK-DAG: alloca_2#0 <-> func.region0.block2#0: NoAlias
39
40// CHECK-DAG: alloc_1#0 <-> func.region0.block1#0: NoAlias
41// CHECK-DAG: alloc_1#0 <-> func.region0.block2#0: NoAlias
42
43// CHECK-DAG: func.region0#0 <-> func.region0.block1#0: NoAlias
44// CHECK-DAG: func.region0#0 <-> func.region0.block2#0: NoAlias
45
46// CHECK-DAG: func.region0#1 <-> func.region0.block1#0: NoAlias
47// CHECK-DAG: func.region0#1 <-> func.region0.block2#0: NoAlias
48
49// CHECK-DAG: func.region0.block1#0 <-> func.region0.block2#0: MustAlias
50func.func @control_flow(%arg: memref<2xf32>, %cond: i1) attributes {test.ptr = "func"} {
51  %0 = memref.alloca() {test.ptr = "alloca_1"} : memref<8x64xf32>
52  %1 = memref.alloca() {test.ptr = "alloca_2"} : memref<8x64xf32>
53  %2 = memref.alloc() {test.ptr = "alloc_1"} : memref<8x64xf32>
54
55  cf.cond_br %cond, ^bb1(%0 : memref<8x64xf32>), ^bb2(%0 : memref<8x64xf32>)
56
57^bb1(%arg1: memref<8x64xf32>):
58  cf.br ^bb2(%arg1 : memref<8x64xf32>)
59
60^bb2(%arg2: memref<8x64xf32>):
61  return
62}
63
64// -----
65
66// CHECK-LABEL: Testing : "control_flow_merge"
67// CHECK-DAG: alloca_1#0 <-> func.region0.block1#0: MustAlias
68// CHECK-DAG: alloca_1#0 <-> func.region0.block2#0: MayAlias
69
70// CHECK-DAG: alloca_2#0 <-> func.region0.block1#0: NoAlias
71// CHECK-DAG: alloca_2#0 <-> func.region0.block2#0: NoAlias
72
73// CHECK-DAG: alloc_1#0 <-> func.region0.block1#0: NoAlias
74// CHECK-DAG: alloc_1#0 <-> func.region0.block2#0: MayAlias
75
76// CHECK-DAG: func.region0#0 <-> func.region0.block1#0: NoAlias
77// CHECK-DAG: func.region0#0 <-> func.region0.block2#0: NoAlias
78
79// CHECK-DAG: func.region0#1 <-> func.region0.block1#0: NoAlias
80// CHECK-DAG: func.region0#1 <-> func.region0.block2#0: NoAlias
81
82// CHECK-DAG: func.region0.block1#0 <-> func.region0.block2#0: MayAlias
83func.func @control_flow_merge(%arg: memref<2xf32>, %cond: i1) attributes {test.ptr = "func"} {
84  %0 = memref.alloca() {test.ptr = "alloca_1"} : memref<8x64xf32>
85  %1 = memref.alloca() {test.ptr = "alloca_2"} : memref<8x64xf32>
86  %2 = memref.alloc() {test.ptr = "alloc_1"} : memref<8x64xf32>
87
88  cf.cond_br %cond, ^bb1(%0 : memref<8x64xf32>), ^bb2(%2 : memref<8x64xf32>)
89
90^bb1(%arg1: memref<8x64xf32>):
91  cf.br ^bb2(%arg1 : memref<8x64xf32>)
92
93^bb2(%arg2: memref<8x64xf32>):
94  return
95}
96
97// -----
98
99// CHECK-LABEL: Testing : "region_control_flow"
100// CHECK-DAG: alloca_1#0 <-> if_alloca#0: MustAlias
101// CHECK-DAG: alloca_1#0 <-> if_alloca_merge#0: MayAlias
102// CHECK-DAG: alloca_1#0 <-> if_alloc#0: NoAlias
103
104// CHECK-DAG: alloca_2#0 <-> if_alloca#0: NoAlias
105// CHECK-DAG: alloca_2#0 <-> if_alloca_merge#0: MayAlias
106// CHECK-DAG: alloca_2#0 <-> if_alloc#0: NoAlias
107
108// CHECK-DAG: alloc_1#0 <-> if_alloca#0: NoAlias
109// CHECK-DAG: alloc_1#0 <-> if_alloca_merge#0: NoAlias
110// CHECK-DAG: alloc_1#0 <-> if_alloc#0: MustAlias
111
112// CHECK-DAG: if_alloca#0 <-> if_alloca_merge#0: MayAlias
113// CHECK-DAG: if_alloca#0 <-> if_alloc#0: NoAlias
114// CHECK-DAG: if_alloca#0 <-> func.region0#0: NoAlias
115// CHECK-DAG: if_alloca#0 <-> func.region0#1: NoAlias
116
117// CHECK-DAG: if_alloca_merge#0 <-> if_alloc#0: NoAlias
118// CHECK-DAG: if_alloca_merge#0 <-> func.region0#0: NoAlias
119// CHECK-DAG: if_alloca_merge#0 <-> func.region0#1: NoAlias
120
121// CHECK-DAG: if_alloc#0 <-> func.region0#0: NoAlias
122// CHECK-DAG: if_alloc#0 <-> func.region0#1: NoAlias
123func.func @region_control_flow(%arg: memref<2xf32>, %cond: i1) attributes {test.ptr = "func"} {
124  %0 = memref.alloca() {test.ptr = "alloca_1"} : memref<8x64xf32>
125  %1 = memref.alloca() {test.ptr = "alloca_2"} : memref<8x64xf32>
126  %2 = memref.alloc() {test.ptr = "alloc_1"} : memref<8x64xf32>
127
128  %3 = scf.if %cond -> (memref<8x64xf32>) {
129    scf.yield %0 : memref<8x64xf32>
130  } else {
131    scf.yield %0 : memref<8x64xf32>
132  } {test.ptr = "if_alloca"}
133
134  %4 = scf.if %cond -> (memref<8x64xf32>) {
135    scf.yield %0 : memref<8x64xf32>
136  } else {
137    scf.yield %1 : memref<8x64xf32>
138  } {test.ptr = "if_alloca_merge"}
139
140  %5 = scf.if %cond -> (memref<8x64xf32>) {
141    scf.yield %2 : memref<8x64xf32>
142  } else {
143    scf.yield %2 : memref<8x64xf32>
144  } {test.ptr = "if_alloc"}
145  return
146}
147
148// -----
149
150// CHECK-LABEL: Testing : "region_loop_control_flow"
151// CHECK-DAG: alloca_1#0 <-> for_alloca#0: MustAlias
152// CHECK-DAG: alloca_1#0 <-> for_alloca.region0#0: MayAlias
153// CHECK-DAG: alloca_1#0 <-> for_alloca.region0#1: MustAlias
154
155// CHECK-DAG: alloca_2#0 <-> for_alloca#0: NoAlias
156// CHECK-DAG: alloca_2#0 <-> for_alloca.region0#0: MayAlias
157// CHECK-DAG: alloca_2#0 <-> for_alloca.region0#1: NoAlias
158
159// CHECK-DAG: alloc_1#0 <-> for_alloca#0: NoAlias
160// CHECK-DAG: alloc_1#0 <-> for_alloca.region0#0: MayAlias
161// CHECK-DAG: alloc_1#0 <-> for_alloca.region0#1: NoAlias
162
163// CHECK-DAG: for_alloca#0 <-> for_alloca.region0#0: MayAlias
164// CHECK-DAG: for_alloca#0 <-> for_alloca.region0#1: MustAlias
165// CHECK-DAG: for_alloca#0 <-> func.region0#0: NoAlias
166// CHECK-DAG: for_alloca#0 <-> func.region0#1: NoAlias
167// CHECK-DAG: for_alloca#0 <-> func.region0#2: NoAlias
168// CHECK-DAG: for_alloca#0 <-> func.region0#3: NoAlias
169
170// CHECK-DAG: for_alloca.region0#0 <-> for_alloca.region0#1: MayAlias
171// CHECK-DAG: for_alloca.region0#0 <-> func.region0#0: MayAlias
172// CHECK-DAG: for_alloca.region0#0 <-> func.region0#1: MayAlias
173// CHECK-DAG: for_alloca.region0#0 <-> func.region0#2: MayAlias
174// CHECK-DAG: for_alloca.region0#0 <-> func.region0#3: MayAlias
175
176// CHECK-DAG: for_alloca.region0#1 <-> func.region0#0: NoAlias
177// CHECK-DAG: for_alloca.region0#1 <-> func.region0#1: NoAlias
178// CHECK-DAG: for_alloca.region0#1 <-> func.region0#2: NoAlias
179// CHECK-DAG: for_alloca.region0#1 <-> func.region0#3: NoAlias
180func.func @region_loop_control_flow(%arg: memref<2xf32>, %loopI0 : index,
181                               %loopI1 : index, %loopI2 : index) attributes {test.ptr = "func"} {
182  %0 = memref.alloca() {test.ptr = "alloca_1"} : memref<8x64xf32>
183  %1 = memref.alloca() {test.ptr = "alloca_2"} : memref<8x64xf32>
184  %2 = memref.alloc() {test.ptr = "alloc_1"} : memref<8x64xf32>
185
186  %result = scf.for %i0 = %loopI0 to %loopI1 step %loopI2 iter_args(%si = %0) -> (memref<8x64xf32>) {
187    scf.yield %si : memref<8x64xf32>
188  } {test.ptr = "for_alloca"}
189  return
190}
191
192// -----
193
194// CHECK-LABEL: Testing : "region_loop_zero_trip_count"
195// CHECK-DAG: alloca_1#0 <-> alloca_2#0: NoAlias
196// CHECK-DAG: alloca_1#0 <-> for_alloca#0: MustAlias
197// CHECK-DAG: alloca_1#0 <-> for_alloca.region0#0: MayAlias
198// CHECK-DAG: alloca_1#0 <-> for_alloca.region0#1: MayAlias
199
200// CHECK-DAG: alloca_2#0 <-> for_alloca#0: NoAlias
201// CHECK-DAG: alloca_2#0 <-> for_alloca.region0#0: MayAlias
202// CHECK-DAG: alloca_2#0 <-> for_alloca.region0#1: MayAlias
203
204// CHECK-DAG: for_alloca#0 <-> for_alloca.region0#0: MayAlias
205// CHECK-DAG: for_alloca#0 <-> for_alloca.region0#1: MayAlias
206
207// CHECK-DAG: for_alloca.region0#0 <-> for_alloca.region0#1: MayAlias
208func.func @region_loop_zero_trip_count() attributes {test.ptr = "func"} {
209  %0 = memref.alloca() {test.ptr = "alloca_1"} : memref<i32>
210  %1 = memref.alloca() {test.ptr = "alloca_2"} : memref<i32>
211  %result = affine.for %i = 0 to 0 iter_args(%si = %0) -> (memref<i32>) {
212    affine.yield %si : memref<i32>
213  } {test.ptr = "for_alloca"}
214  return
215}
216
217// -----
218
219// CHECK-LABEL: Testing : "view_like"
220// CHECK-DAG: alloc_1#0 <-> view#0: NoAlias
221
222// CHECK-DAG: alloca_1#0 <-> view#0: MustAlias
223
224// CHECK-DAG: view#0 <-> func.region0#0: NoAlias
225// CHECK-DAG: view#0 <-> func.region0#1: NoAlias
226func.func @view_like(%arg: memref<2xf32>, %size: index) attributes {test.ptr = "func"} {
227  %1 = memref.alloc() {test.ptr = "alloc_1"} : memref<8x64xf32>
228
229  %c0 = arith.constant 0 : index
230  %2 = memref.alloca (%size) {test.ptr = "alloca_1"} : memref<?xi8>
231  %3 = memref.view %2[%c0][] {test.ptr = "view"} : memref<?xi8> to memref<8x64xf32>
232  return
233}
234
235// -----
236
237// CHECK-LABEL: Testing : "constants"
238// CHECK-DAG: alloc_1#0 <-> constant_1#0: NoAlias
239// CHECK-DAG: alloc_1#0 <-> constant_2#0: NoAlias
240// CHECK-DAG: alloc_1#0 <-> constant_3#0: NoAlias
241
242// CHECK-DAG: constant_1#0 <-> constant_2#0: MayAlias
243// CHECK-DAG: constant_1#0 <-> constant_3#0: MayAlias
244// CHECK-DAG: constant_1#0 <-> func.region0#0: MayAlias
245
246// CHECK-DAG: constant_2#0 <-> constant_3#0: MayAlias
247// CHECK-DAG: constant_2#0 <-> func.region0#0: MayAlias
248
249// CHECK-DAG: constant_3#0 <-> func.region0#0: MayAlias
250func.func @constants(%arg: memref<2xf32>) attributes {test.ptr = "func"} {
251  %1 = memref.alloc() {test.ptr = "alloc_1"} : memref<8x64xf32>
252
253  %c0 = arith.constant {test.ptr = "constant_1"} 0 : index
254  %c0_2 = arith.constant {test.ptr = "constant_2"} 0 : index
255  %c1 = arith.constant {test.ptr = "constant_3"} 1 : index
256
257  return
258}
259