[MLIR][TOSA] Update CustomOp input and output names (#118408)
[llvm-project.git] / mlir / test / Analysis / DataFlow / test-last-modified-callgraph.mlir
bloba5eba43ac68ab144dac83f167ba79b3ede88b148
1 // RUN: mlir-opt -test-last-modified --split-input-file %s 2>&1 |\
2 // RUN:          FileCheck %s --check-prefixes=CHECK,IP,IP_ONLY
3 // RUN: mlir-opt -test-last-modified='assume-func-writes=true' \
4 // RUN:          --split-input-file %s 2>&1 |\
5 // RUN:          FileCheck %s --check-prefixes=CHECK,IP,IP_AW
6 // RUN: mlir-opt -test-last-modified='interprocedural=false' \
7 // RUN:          --split-input-file %s 2>&1 |\
8 // RUN:          FileCheck %s --check-prefixes=CHECK,LOCAL
9 // RUN: mlir-opt \
10 // RUN:    -test-last-modified='interprocedural=false assume-func-writes=true' \
11 // RUN:    --split-input-file %s 2>&1 |\
12 // RUN:    FileCheck %s --check-prefixes=CHECK,LC_AW
14 // Check prefixes are as follows:
15 // 'check': common for all runs;
16 // 'ip': interprocedural runs;
17 // 'ip_aw': interpocedural runs assuming calls to external functions write to
18 //          all arguments;
19 // 'ip_only': interprocedural runs not assuming calls writing;
20 // 'local': local (non-interprocedural) analysis not assuming calls writing;
21 // 'lc_aw': local analysis assuming external calls writing to all arguments.
23 // CHECK-LABEL: test_tag: test_callsite
24 // IP:    operand #0
25 // IP-NEXT: - a
26 // LOCAL: operand #0
27 // LOCAL-NEXT: - <unknown>
28 // LC_AW: operand #0
29 // LC_AW-NEXT: - <unknown>
30 func.func private @single_callsite_fn(%ptr: memref<i32>) -> memref<i32> {
31   return {tag = "test_callsite"} %ptr : memref<i32>
34 func.func @test_callsite() {
35   %ptr = memref.alloc() : memref<i32>
36   %c0 = arith.constant 0 : i32
37   memref.store %c0, %ptr[] {tag_name = "a"} : memref<i32>
38   %0 = func.call @single_callsite_fn(%ptr) : (memref<i32>) -> memref<i32>
39   return
42 // CHECK-LABEL: test_tag: test_return_site
43 // IP:    operand #0
44 // IP-NEXT:    - b
45 // LOCAL: operand #0
46 // LOCAL-NEXT: - <unknown>
47 // LC_AW: operand #0
48 // LC_AW-NEXT: - <unknown>
49 func.func private @single_return_site_fn(%ptr: memref<i32>) -> memref<i32> {
50   %c0 = arith.constant 0 : i32
51   memref.store %c0, %ptr[] {tag_name = "b"} : memref<i32>
52   return %ptr : memref<i32>
55 // CHECK-LABEL: test_tag: test_multiple_callsites
56 // IP:    operand #0
57 // IP-NEXT:    write0
58 // IP-NEXT:    write1
59 // LOCAL: operand #0
60 // LOCAL-NEXT: - <unknown>
61 // LC_AW: operand #0
62 // LC_AW-NEXT: - <unknown>
63 func.func @test_return_site(%ptr: memref<i32>) -> memref<i32> {
64   %0 = func.call @single_return_site_fn(%ptr) : (memref<i32>) -> memref<i32>
65   return {tag = "test_return_site"} %0 : memref<i32>
68 func.func private @multiple_callsite_fn(%ptr: memref<i32>) -> memref<i32> {
69   return {tag = "test_multiple_callsites"} %ptr : memref<i32>
72 func.func @test_multiple_callsites(%a: i32, %ptr: memref<i32>) -> memref<i32> {
73   memref.store %a, %ptr[] {tag_name = "write0"} : memref<i32>
74   %0 = func.call @multiple_callsite_fn(%ptr) : (memref<i32>) -> memref<i32>
75   memref.store %a, %ptr[] {tag_name = "write1"} : memref<i32>
76   %1 = func.call @multiple_callsite_fn(%ptr) : (memref<i32>) -> memref<i32>
77   return %ptr : memref<i32>
80 // CHECK-LABEL: test_tag: test_multiple_return_sites
81 // IP:    operand #0
82 // IP-NEXT:    return0
83 // IP-NEXT:    return1
84 // LOCAL: operand #0
85 // LOCAL-NEXT: - <unknown>
86 // LC_AW: operand #0
87 // LC_AW-NEXT: - <unknown>
88 func.func private @multiple_return_site_fn(%cond: i1, %a: i32, %ptr: memref<i32>) -> memref<i32> {
89   cf.cond_br %cond, ^a, ^b
91 ^a:
92   memref.store %a, %ptr[] {tag_name = "return0"} : memref<i32>
93   return %ptr : memref<i32>
95 ^b:
96   memref.store %a, %ptr[] {tag_name = "return1"} : memref<i32>
97   return %ptr : memref<i32>
100 func.func @test_multiple_return_sites(%cond: i1, %a: i32, %ptr: memref<i32>) -> memref<i32> {
101   %0 = func.call @multiple_return_site_fn(%cond, %a, %ptr) : (i1, i32, memref<i32>) -> memref<i32>
102   return {tag = "test_multiple_return_sites"} %0 : memref<i32>
105 // -----
107 // CHECK-LABEL: test_tag: after_call
108 // IP:    operand #0
109 // IP-NEXT:    - write0
110 // LOCAL: operand #0
111 // LOCAL-NEXT: - <unknown>
112 // LC_AW: operand #0
113 // LC_AW-NEXT: - func.call
114 func.func private @void_return(%ptr: memref<i32>) {
115   return
118 func.func @test_call_void_return() {
119   %ptr = memref.alloc() : memref<i32>
120   %c0 = arith.constant 0 : i32
121   memref.store %c0, %ptr[] {tag_name = "write0"} : memref<i32>
122   func.call @void_return(%ptr) : (memref<i32>) -> ()
123   memref.load %ptr[] {tag = "after_call"} : memref<i32>
124   return
127 // -----
129 func.func private @callee(%arg0: memref<f32>) -> memref<f32> {
130   %2 = arith.constant 2.0 : f32
131   memref.load %arg0[] {tag = "call_and_store_before::enter_callee"} : memref<f32>
132   memref.store %2, %arg0[] {tag_name = "callee"} : memref<f32>
133   memref.load %arg0[] {tag = "exit_callee"} : memref<f32>
134   return %arg0 : memref<f32>
136 // In this test, the "call" operation also stores to %arg0 itself before
137 // transferring control flow to the callee. Therefore, the order of accesses is
138 // "pre" -> "call" -> "callee" -> "post"
140 // CHECK-LABEL: test_tag: call_and_store_before::enter_callee:
141 // IP:     operand #0
142 // IP:      - call
143 // LOCAL:  operand #0
144 // LOCAL:   - <unknown>
145 // LC_AW:  operand #0
146 // LC_AW:   - <unknown>
148 // CHECK: test_tag: exit_callee:
149 // CHECK:  operand #0
150 // CHECK:   - callee
152 // CHECK: test_tag: before_call:
153 // CHECK:  operand #0
154 // CHECK:   - pre
156 // CHECK: test_tag: after_call:
157 // IP:     operand #0
158 // IP:      - callee
159 // LOCAL:  operand #0
160 // LOCAL:   - <unknown>
161 // LC_AW:  operand #0
162 // LC_AW:   - call
164 // CHECK: test_tag: return:
165 // CHECK:  operand #0
166 // CHECK:   - post
167 func.func @call_and_store_before(%arg0: memref<f32>) -> memref<f32> {
168   %0 = arith.constant 0.0 : f32
169   %1 = arith.constant 1.0 : f32
170   memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>
171   memref.load %arg0[] {tag = "before_call"} : memref<f32>
172   test.call_and_store @callee(%arg0), %arg0 {tag_name = "call", store_before_call = true} : (memref<f32>, memref<f32>) -> ()
173   memref.load %arg0[] {tag = "after_call"} : memref<f32>
174   memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>
175   return {tag = "return"} %arg0 : memref<f32>
178 // -----
180 func.func private @callee(%arg0: memref<f32>) -> memref<f32> {
181   %2 = arith.constant 2.0 : f32
182   memref.load %arg0[] {tag = "call_and_store_after::enter_callee"} : memref<f32>
183   memref.store %2, %arg0[] {tag_name = "callee"} : memref<f32>
184   memref.load %arg0[] {tag = "exit_callee"} : memref<f32>
185   return %arg0 : memref<f32>
188 // In this test, the "call" operation also stores to %arg0 itself after getting
189 // control flow back from the callee. Therefore, the order of accesses is
190 // "pre" -> "callee" -> "call" -> "post"
192 // CHECK-LABEL: test_tag: call_and_store_after::enter_callee:
193 // IP:     operand #0
194 // IP:      - pre
195 // LOCAL:  operand #0
196 // LOCAL:   - <unknown>
197 // LC_AW:  operand #0
198 // LC_AW:   - <unknown>
200 // CHECK: test_tag: exit_callee:
201 // CHECK:  operand #0
202 // CHECK:   - callee
204 // CHECK: test_tag: before_call:
205 // CHECK:  operand #0
206 // CHECK:   - pre
208 // CHECK:    test_tag: after_call:
209 // IP:     operand #0
210 // IP:      - call
211 // LOCAL:  operand #0
212 // LOCAL:   - <unknown>
213 // LC_AW:  operand #0
214 // LC_AW:   - call
216 // CHECK: test_tag: return:
217 // CHECK:  operand #0
218 // CHECK:   - post
219 func.func @call_and_store_after(%arg0: memref<f32>) -> memref<f32> {
220   %0 = arith.constant 0.0 : f32
221   %1 = arith.constant 1.0 : f32
222   memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>
223   memref.load %arg0[] {tag = "before_call"} : memref<f32>
224   test.call_and_store @callee(%arg0), %arg0 {tag_name = "call", store_before_call = false} : (memref<f32>, memref<f32>) -> ()
225   memref.load %arg0[] {tag = "after_call"} : memref<f32>
226   memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>
227   return {tag = "return"} %arg0 : memref<f32>
230 // -----
232 func.func private @void_return(%ptr: memref<i32>)
234 // CHECK-LABEL: test_tag: after_opaque_call:
235 // CHECK:        operand #0
236 // IP_ONLY:       - <unknown>
237 // IP_AW:         - func.call
238 func.func @test_opaque_call_return() {
239   %ptr = memref.alloc() : memref<i32>
240   %c0 = arith.constant 0 : i32
241   memref.store %c0, %ptr[] {tag_name = "write0"} : memref<i32>
242   func.call @void_return(%ptr) : (memref<i32>) -> ()
243   memref.load %ptr[] {tag = "after_opaque_call"} : memref<i32>
244   return