1 // RUN: mlir-opt -test-last-modified %s 2>&1 | FileCheck %s
3 // CHECK-LABEL: test_tag: test_simple_mod
8 func.func @test_simple_mod(%arg0: memref<i32>, %arg1: memref<i32>) -> (memref<i32>, memref<i32>) {
9 %c0 = arith.constant 0 : i32
10 %c1 = arith.constant 1 : i32
11 memref.store %c0, %arg0[] {tag_name = "a"} : memref<i32>
12 memref.store %c1, %arg1[] {tag_name = "b"} : memref<i32>
13 return {tag = "test_simple_mod"} %arg0, %arg1 : memref<i32>, memref<i32>
16 // CHECK-LABEL: test_tag: test_simple_mod_overwrite_a
19 // CHECK-LABEL: test_tag: test_simple_mod_overwrite_b
22 func.func @test_simple_mod_overwrite(%arg0: memref<i32>) -> memref<i32> {
23 %c0 = arith.constant 0 : i32
24 memref.store %c0, %arg0[] {tag = "test_simple_mod_overwrite_a", tag_name = "a"} : memref<i32>
25 %c1 = arith.constant 1 : i32
26 memref.store %c1, %arg0[] {tag_name = "b"} : memref<i32>
27 return {tag = "test_simple_mod_overwrite_b"} %arg0 : memref<i32>
30 // CHECK-LABEL: test_tag: test_mod_control_flow
34 func.func @test_mod_control_flow(%cond: i1, %ptr: memref<i32>) -> memref<i32> {
35 cf.cond_br %cond, ^a, ^b
38 %c0 = arith.constant 0 : i32
39 memref.store %c0, %ptr[] {tag_name = "a"} : memref<i32>
43 %c1 = arith.constant 1 : i32
44 memref.store %c1, %ptr[] {tag_name = "b"} : memref<i32>
48 return {tag = "test_mod_control_flow"} %ptr : memref<i32>
51 // CHECK-LABEL: test_tag: test_mod_dead_branch
54 func.func @test_mod_dead_branch(%arg: i32, %ptr: memref<i32>) -> memref<i32> {
55 %0 = arith.subi %arg, %arg : i32
56 %1 = arith.constant -1 : i32
57 %2 = arith.cmpi sgt, %0, %1 : i32
61 %c0 = arith.constant 0 : i32
62 memref.store %c0, %ptr[] {tag_name = "a"} : memref<i32>
66 %c1 = arith.constant 1 : i32
67 memref.store %c1, %ptr[] {tag_name = "b"} : memref<i32>
71 return {tag = "test_mod_dead_branch"} %ptr : memref<i32>
74 // CHECK-LABEL: test_tag: test_mod_region_control_flow
78 func.func @test_mod_region_control_flow(%cond: i1, %ptr: memref<i32>) -> memref<i32> {
80 %c0 = arith.constant 0 : i32
81 memref.store %c0, %ptr[] {tag_name = "then"}: memref<i32>
83 %c1 = arith.constant 1 : i32
84 memref.store %c1, %ptr[] {tag_name = "else"} : memref<i32>
86 return {tag = "test_mod_region_control_flow"} %ptr : memref<i32>
89 // CHECK-LABEL: test_tag: test_mod_dead_region
92 func.func @test_mod_dead_region(%ptr: memref<i32>) -> memref<i32> {
93 %false = arith.constant false
95 %c0 = arith.constant 0 : i32
96 memref.store %c0, %ptr[] {tag_name = "then"}: memref<i32>
98 %c1 = arith.constant 1 : i32
99 memref.store %c1, %ptr[] {tag_name = "else"} : memref<i32>
101 return {tag = "test_mod_dead_region"} %ptr : memref<i32>
104 // CHECK-LABEL: test_tag: unknown_memory_effects_a
107 // CHECK-LABEL: test_tag: unknown_memory_effects_b
109 // CHECK-NEXT: - <unknown>
110 func.func @unknown_memory_effects(%ptr: memref<i32>) -> memref<i32> {
111 %c0 = arith.constant 0 : i32
112 memref.store %c0, %ptr[] {tag = "unknown_memory_effects_a", tag_name = "a"} : memref<i32>
113 "test.unknown_effects"() : () -> ()
114 return {tag = "unknown_memory_effects_b"} %ptr : memref<i32>
117 // CHECK-LABEL: test_tag: store_with_a_region_before::before:
120 // CHECK: test_tag: inside_region:
123 // CHECK: test_tag: after:
126 // CHECK: test_tag: return:
129 func.func @store_with_a_region_before(%arg0: memref<f32>) -> memref<f32> {
130 %0 = arith.constant 0.0 : f32
131 %1 = arith.constant 1.0 : f32
132 memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>
133 memref.load %arg0[] {tag = "store_with_a_region_before::before"} : memref<f32>
134 test.store_with_a_region %arg0 attributes { tag_name = "region", store_before_region = true } {
135 memref.load %arg0[] {tag = "inside_region"} : memref<f32>
136 test.store_with_a_region_terminator
138 memref.load %arg0[] {tag = "after"} : memref<f32>
139 memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>
140 return {tag = "return"} %arg0 : memref<f32>
143 // CHECK-LABEL: test_tag: store_with_a_region_after::before:
146 // CHECK: test_tag: inside_region:
149 // CHECK: test_tag: after:
152 // CHECK: test_tag: return:
155 func.func @store_with_a_region_after(%arg0: memref<f32>) -> memref<f32> {
156 %0 = arith.constant 0.0 : f32
157 %1 = arith.constant 1.0 : f32
158 memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>
159 memref.load %arg0[] {tag = "store_with_a_region_after::before"} : memref<f32>
160 test.store_with_a_region %arg0 attributes { tag_name = "region", store_before_region = false } {
161 memref.load %arg0[] {tag = "inside_region"} : memref<f32>
162 test.store_with_a_region_terminator
164 memref.load %arg0[] {tag = "after"} : memref<f32>
165 memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>
166 return {tag = "return"} %arg0 : memref<f32>
169 // CHECK-LABEL: test_tag: store_with_a_region_before_containing_a_store::before:
172 // CHECK: test_tag: enter_region:
175 // CHECK: test_tag: exit_region:
178 // CHECK: test_tag: after:
181 // CHECK: test_tag: return:
184 func.func @store_with_a_region_before_containing_a_store(%arg0: memref<f32>) -> memref<f32> {
185 %0 = arith.constant 0.0 : f32
186 %1 = arith.constant 1.0 : f32
187 memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>
188 memref.load %arg0[] {tag = "store_with_a_region_before_containing_a_store::before"} : memref<f32>
189 test.store_with_a_region %arg0 attributes { tag_name = "region", store_before_region = true } {
190 memref.load %arg0[] {tag = "enter_region"} : memref<f32>
191 %2 = arith.constant 2.0 : f32
192 memref.store %2, %arg0[] {tag_name = "inner"} : memref<f32>
193 memref.load %arg0[] {tag = "exit_region"} : memref<f32>
194 test.store_with_a_region_terminator
196 memref.load %arg0[] {tag = "after"} : memref<f32>
197 memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>
198 return {tag = "return"} %arg0 : memref<f32>
201 // CHECK-LABEL: test_tag: store_with_a_region_after_containing_a_store::before:
204 // CHECK: test_tag: enter_region:
207 // CHECK: test_tag: exit_region:
210 // CHECK: test_tag: after:
213 // CHECK: test_tag: return:
216 func.func @store_with_a_region_after_containing_a_store(%arg0: memref<f32>) -> memref<f32> {
217 %0 = arith.constant 0.0 : f32
218 %1 = arith.constant 1.0 : f32
219 memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>
220 memref.load %arg0[] {tag = "store_with_a_region_after_containing_a_store::before"} : memref<f32>
221 test.store_with_a_region %arg0 attributes { tag_name = "region", store_before_region = false } {
222 memref.load %arg0[] {tag = "enter_region"} : memref<f32>
223 %2 = arith.constant 2.0 : f32
224 memref.store %2, %arg0[] {tag_name = "inner"} : memref<f32>
225 memref.load %arg0[] {tag = "exit_region"} : memref<f32>
226 test.store_with_a_region_terminator
228 memref.load %arg0[] {tag = "after"} : memref<f32>
229 memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>
230 return {tag = "return"} %arg0 : memref<f32>
233 // CHECK-LABEL: test_tag: store_with_a_loop_region_before::before:
236 // CHECK: test_tag: inside_region:
239 // CHECK: test_tag: after:
242 // CHECK: test_tag: return:
245 func.func @store_with_a_loop_region_before(%arg0: memref<f32>) -> memref<f32> {
246 %0 = arith.constant 0.0 : f32
247 %1 = arith.constant 1.0 : f32
248 memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>
249 memref.load %arg0[] {tag = "store_with_a_loop_region_before::before"} : memref<f32>
250 test.store_with_a_loop_region %arg0 attributes { tag_name = "region", store_before_region = true } {
251 memref.load %arg0[] {tag = "inside_region"} : memref<f32>
252 test.store_with_a_region_terminator
254 memref.load %arg0[] {tag = "after"} : memref<f32>
255 memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>
256 return {tag = "return"} %arg0 : memref<f32>
259 // CHECK-LABEL: test_tag: store_with_a_loop_region_after::before:
262 // CHECK: test_tag: inside_region:
265 // CHECK: test_tag: after:
268 // CHECK: test_tag: return:
271 func.func @store_with_a_loop_region_after(%arg0: memref<f32>) -> memref<f32> {
272 %0 = arith.constant 0.0 : f32
273 %1 = arith.constant 1.0 : f32
274 memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>
275 memref.load %arg0[] {tag = "store_with_a_loop_region_after::before"} : memref<f32>
276 test.store_with_a_loop_region %arg0 attributes { tag_name = "region", store_before_region = false } {
277 memref.load %arg0[] {tag = "inside_region"} : memref<f32>
278 test.store_with_a_region_terminator
280 memref.load %arg0[] {tag = "after"} : memref<f32>
281 memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>
282 return {tag = "return"} %arg0 : memref<f32>
285 // CHECK-LABEL: test_tag: store_with_a_loop_region_before_containing_a_store::before:
288 // CHECK: test_tag: enter_region:
290 // CHECK-DAG: - region
291 // CHECK-DAG: - inner
292 // CHECK: test_tag: exit_region:
295 // CHECK: test_tag: after:
297 // CHECK-DAG: - region
298 // CHECK-DAG: - inner
299 // CHECK: test_tag: return:
302 func.func @store_with_a_loop_region_before_containing_a_store(%arg0: memref<f32>) -> memref<f32> {
303 %0 = arith.constant 0.0 : f32
304 %1 = arith.constant 1.0 : f32
305 memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>
306 memref.load %arg0[] {tag = "store_with_a_loop_region_before_containing_a_store::before"} : memref<f32>
307 test.store_with_a_loop_region %arg0 attributes { tag_name = "region", store_before_region = true } {
308 memref.load %arg0[] {tag = "enter_region"} : memref<f32>
309 %2 = arith.constant 2.0 : f32
310 memref.store %2, %arg0[] {tag_name = "inner"} : memref<f32>
311 memref.load %arg0[] {tag = "exit_region"} : memref<f32>
312 test.store_with_a_region_terminator
314 memref.load %arg0[] {tag = "after"} : memref<f32>
315 memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>
316 return {tag = "return"} %arg0 : memref<f32>
319 // CHECK-LABEL: test_tag: store_with_a_loop_region_after_containing_a_store::before:
322 // CHECK: test_tag: enter_region:
325 // CHECK-DAG: - inner
326 // CHECK: test_tag: exit_region:
329 // CHECK: test_tag: after:
332 // CHECK: test_tag: return:
335 func.func @store_with_a_loop_region_after_containing_a_store(%arg0: memref<f32>) -> memref<f32> {
336 %0 = arith.constant 0.0 : f32
337 %1 = arith.constant 1.0 : f32
338 memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>
339 memref.load %arg0[] {tag = "store_with_a_loop_region_after_containing_a_store::before"} : memref<f32>
340 test.store_with_a_loop_region %arg0 attributes { tag_name = "region", store_before_region = false } {
341 memref.load %arg0[] {tag = "enter_region"} : memref<f32>
342 %2 = arith.constant 2.0 : f32
343 memref.store %2, %arg0[] {tag_name = "inner"} : memref<f32>
344 memref.load %arg0[] {tag = "exit_region"} : memref<f32>
345 test.store_with_a_region_terminator
347 memref.load %arg0[] {tag = "after"} : memref<f32>
348 memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>
349 return {tag = "return"} %arg0 : memref<f32>