1// RUN: mlir-opt %s -test-print-liveness -split-input-file 2>&1 | FileCheck %s
2
3// CHECK-LABEL: Testing : func_empty
4func @func_empty() {
5  // CHECK: Block: 0
6  // CHECK-NEXT: LiveIn:{{ *$}}
7  // CHECK-NEXT: LiveOut:{{ *$}}
8  // CHECK-NEXT: BeginLiveness
9  // CHECK-NEXT: EndLiveness
10  return
11}
12
13// -----
14
15// CHECK-LABEL: Testing : func_simpleBranch
16func @func_simpleBranch(%arg0: i32, %arg1 : i32) -> i32 {
17  // CHECK: Block: 0
18  // CHECK-NEXT: LiveIn:{{ *$}}
19  // CHECK-NEXT: LiveOut: arg0@0 arg1@0
20  // CHECK-NEXT: BeginLiveness
21  // CHECK-NEXT: EndLiveness
22  br ^exit
23^exit:
24  // CHECK: Block: 1
25  // CHECK-NEXT: LiveIn: arg0@0 arg1@0
26  // CHECK-NEXT: LiveOut:{{ *$}}
27  // CHECK-NEXT: BeginLiveness
28  // CHECK: val_2
29  // CHECK-NEXT:     %0 = addi
30  // CHECK-NEXT:     return
31  // CHECK-NEXT: EndLiveness
32  %result = addi %arg0, %arg1 : i32
33  return %result : i32
34}
35
36// -----
37
38// CHECK-LABEL: Testing : func_condBranch
39func @func_condBranch(%cond : i1, %arg1: i32, %arg2 : i32) -> i32 {
40  // CHECK: Block: 0
41  // CHECK-NEXT: LiveIn:{{ *$}}
42  // CHECK-NEXT: LiveOut: arg1@0 arg2@0
43  // CHECK-NEXT: BeginLiveness
44  // CHECK-NEXT: EndLiveness
45  cond_br %cond, ^bb1, ^bb2
46^bb1:
47  // CHECK: Block: 1
48  // CHECK-NEXT: LiveIn: arg1@0 arg2@0
49  // CHECK-NEXT: LiveOut: arg1@0 arg2@0
50  br ^exit
51^bb2:
52  // CHECK: Block: 2
53  // CHECK-NEXT: LiveIn: arg1@0 arg2@0
54  // CHECK-NEXT: LiveOut: arg1@0 arg2@0
55  br ^exit
56^exit:
57  // CHECK: Block: 3
58  // CHECK-NEXT: LiveIn: arg1@0 arg2@0
59  // CHECK-NEXT: LiveOut:{{ *$}}
60  // CHECK-NEXT: BeginLiveness
61  // CHECK: val_3
62  // CHECK-NEXT:     %0 = addi
63  // CHECK-NEXT:     return
64  // CHECK-NEXT: EndLiveness
65  %result = addi %arg1, %arg2 : i32
66  return %result : i32
67}
68
69// -----
70
71// CHECK-LABEL: Testing : func_loop
72func @func_loop(%arg0 : i32, %arg1 : i32) -> i32 {
73  // CHECK: Block: 0
74  // CHECK-NEXT: LiveIn:{{ *$}}
75  // CHECK-NEXT: LiveOut: arg1@0
76  %const0 = constant 0 : i32
77  br ^loopHeader(%const0, %arg0 : i32, i32)
78^loopHeader(%counter : i32, %i : i32):
79  // CHECK: Block: 1
80  // CHECK-NEXT: LiveIn: arg1@0
81  // CHECK-NEXT: LiveOut: arg1@0 arg0@1
82  // CHECK-NEXT: BeginLiveness
83  // CHECK-NEXT: val_5
84  // CHECK-NEXT:     %2 = cmpi
85  // CHECK-NEXT:     cond_br
86  // CHECK-NEXT: EndLiveness
87  %lessThan = cmpi slt, %counter, %arg1 : i32
88  cond_br %lessThan, ^loopBody(%i : i32), ^exit(%i : i32)
89^loopBody(%val : i32):
90  // CHECK: Block: 2
91  // CHECK-NEXT: LiveIn: arg1@0 arg0@1
92  // CHECK-NEXT: LiveOut: arg1@0
93  // CHECK-NEXT: BeginLiveness
94  // CHECK-NEXT: val_7
95  // CHECK-NEXT:     %c
96  // CHECK-NEXT:     %4 = addi
97  // CHECK-NEXT:     %5 = addi
98  // CHECK-NEXT: val_8
99  // CHECK-NEXT:     %4 = addi
100  // CHECK-NEXT:     %5 = addi
101  // CHECK-NEXT:     br
102  // CHECK: EndLiveness
103  %const1 = constant 1 : i32
104  %inc = addi %val, %const1 : i32
105  %inc2 = addi %counter, %const1 : i32
106  br ^loopHeader(%inc, %inc2 : i32, i32)
107^exit(%sum : i32):
108  // CHECK: Block: 3
109  // CHECK-NEXT: LiveIn: arg1@0
110  // CHECK-NEXT: LiveOut:{{ *$}}
111  %result = addi %sum, %arg1 : i32
112  return %result : i32
113}
114
115// -----
116
117// CHECK-LABEL: Testing : func_ranges
118func @func_ranges(%cond : i1, %arg1 : i32, %arg2 : i32, %arg3 : i32) -> i32 {
119  // CHECK: Block: 0
120  // CHECK-NEXT: LiveIn:{{ *$}}
121  // CHECK-NEXT: LiveOut: arg2@0 val_9 val_10
122  // CHECK-NEXT: BeginLiveness
123  // CHECK-NEXT: val_4
124  // CHECK-NEXT:    %0 = addi
125  // CHECK-NEXT:    %c
126  // CHECK-NEXT:    %1 = addi
127  // CHECK-NEXT:    %2 = addi
128  // CHECK-NEXT:    %3 = muli
129  // CHECK-NEXT: val_5
130  // CHECK-NEXT:    %c
131  // CHECK-NEXT:    %1 = addi
132  // CHECK-NEXT:    %2 = addi
133  // CHECK-NEXT:    %3 = muli
134  // CHECK-NEXT:    %4 = muli
135  // CHECK-NEXT:    %5 = addi
136  // CHECK-NEXT: val_6
137  // CHECK-NEXT:    %1 = addi
138  // CHECK-NEXT:    %2 = addi
139  // CHECK-NEXT:    %3 = muli
140  // CHECK-NEXT: val_7
141  // CHECK-NEXT    %2 = addi
142  // CHECK-NEXT    %3 = muli
143  // CHECK-NEXT    %4 = muli
144  // CHECK:      val_8
145  // CHECK-NEXT:    %3 = muli
146  // CHECK-NEXT:    %4 = muli
147  // CHECK-NEXT: val_9
148  // CHECK-NEXT:    %4 = muli
149  // CHECK-NEXT:    %5 = addi
150  // CHECK-NEXT:    cond_br
151  // CHECK-NEXT:    %c
152  // CHECK-NEXT:    %6 = muli
153  // CHECK-NEXT:    %7 = muli
154  // CHECK-NEXT:    %8 = addi
155  // CHECK-NEXT: val_10
156  // CHECK-NEXT:    %5 = addi
157  // CHECK-NEXT:    cond_br
158  // CHECK-NEXT:    %7
159  // CHECK: EndLiveness
160  %0 = addi %arg1, %arg2 : i32
161  %const1 = constant 1 : i32
162  %1 = addi %const1, %arg2 : i32
163  %2 = addi %const1, %arg3 : i32
164  %3 = muli %0, %1 : i32
165  %4 = muli %3, %2 : i32
166  %5 = addi %4, %const1 : i32
167  cond_br %cond, ^bb1, ^bb2
168
169^bb1:
170  // CHECK: Block: 1
171  // CHECK-NEXT: LiveIn: arg2@0 val_9
172  // CHECK-NEXT: LiveOut: arg2@0
173  %const4 = constant 4 : i32
174  %6 = muli %4, %const4 : i32
175  br ^exit(%6 : i32)
176
177^bb2:
178  // CHECK: Block: 2
179  // CHECK-NEXT: LiveIn: arg2@0 val_9 val_10
180  // CHECK-NEXT: LiveOut: arg2@0
181  %7 = muli %4, %5 : i32
182  %8 = addi %4, %arg2 : i32
183  br ^exit(%8 : i32)
184
185^exit(%sum : i32):
186  // CHECK: Block: 3
187  // CHECK-NEXT: LiveIn: arg2@0
188  // CHECK-NEXT: LiveOut:{{ *$}}
189  %result = addi %sum, %arg2 : i32
190  return %result : i32
191}
192
193// -----
194
195// CHECK-LABEL: Testing : nested_region
196
197func @nested_region(
198  %arg0 : index, %arg1 : index, %arg2 : index,
199  %arg3 : i32, %arg4 : i32, %arg5 : i32,
200  %buffer : memref<i32>) -> i32 {
201  // CHECK: Block: 0
202  // CHECK-NEXT: LiveIn:{{ *$}}
203  // CHECK-NEXT: LiveOut:{{ *$}}
204  // CHECK-NEXT: BeginLiveness
205  // CHECK-NEXT: val_7
206  // CHECK-NEXT:    %0 = addi
207  // CHECK-NEXT:    %1 = addi
208  // CHECK-NEXT:    scf.for
209  // CHECK:         // %2 = addi
210  // CHECK-NEXT:    %3 = addi
211  // CHECK-NEXT: val_8
212  // CHECK-NEXT:    %1 = addi
213  // CHECK-NEXT:    scf.for
214  // CHECK:         // return %1
215  // CHECK: EndLiveness
216  %0 = addi %arg3, %arg4 : i32
217  %1 = addi %arg4, %arg5 : i32
218  scf.for %arg6 = %arg0 to %arg1 step %arg2 {
219    // CHECK: Block: 1
220    // CHECK-NEXT: LiveIn: arg5@0 arg6@0 val_7
221    // CHECK-NEXT: LiveOut:{{ *$}}
222    %2 = addi %0, %arg5 : i32
223    %3 = addi %2, %0 : i32
224    store %3, %buffer[] : memref<i32>
225  }
226  return %1 : i32
227}
228
229// -----
230
231// CHECK-LABEL: Testing : nested_region2
232
233func @nested_region2(
234  // CHECK: Block: 0
235  // CHECK-NEXT: LiveIn:{{ *$}}
236  // CHECK-NEXT: LiveOut:{{ *$}}
237  // CHECK-NEXT: BeginLiveness
238  // CHECK-NEXT: val_7
239  // CHECK-NEXT:    %0 = addi
240  // CHECK-NEXT:    %1 = addi
241  // CHECK-NEXT:    scf.for
242  // CHECK:         // %2 = addi
243  // CHECK-NEXT:    scf.for
244  // CHECK:         // %3 = addi
245  // CHECK-NEXT: val_8
246  // CHECK-NEXT:    %1 = addi
247  // CHECK-NEXT:    scf.for
248  // CHECK:         // return %1
249  // CHECK: EndLiveness
250  %arg0 : index, %arg1 : index, %arg2 : index,
251  %arg3 : i32, %arg4 : i32, %arg5 : i32,
252  %buffer : memref<i32>) -> i32 {
253  %0 = addi %arg3, %arg4 : i32
254  %1 = addi %arg4, %arg5 : i32
255  scf.for %arg6 = %arg0 to %arg1 step %arg2 {
256    // CHECK: Block: 1
257    // CHECK-NEXT: LiveIn: arg0@0 arg1@0 arg2@0 arg5@0 arg6@0 val_7
258    // CHECK-NEXT: LiveOut:{{ *$}}
259    // CHECK-NEXT: BeginLiveness
260    // CHECK-NEXT: val_10
261    // CHECK-NEXT:    %2 = addi
262    // CHECK-NEXT:    scf.for
263    // CHECK:         // %3 = addi
264    // CHECK: EndLiveness
265    %2 = addi %0, %arg5 : i32
266    scf.for %arg7 = %arg0 to %arg1 step %arg2 {
267      %3 = addi %2, %0 : i32
268      store %3, %buffer[] : memref<i32>
269    }
270  }
271  return %1 : i32
272}
273
274// -----
275
276// CHECK-LABEL: Testing : nested_region3
277
278func @nested_region3(
279  // CHECK: Block: 0
280  // CHECK-NEXT: LiveIn:{{ *$}}
281  // CHECK-NEXT: LiveOut: arg0@0 arg1@0 arg2@0 arg6@0 val_7 val_8
282  // CHECK-NEXT: BeginLiveness
283  // CHECK-NEXT: val_7
284  // CHECK-NEXT:    %0 = addi
285  // CHECK-NEXT:    %1 = addi
286  // CHECK-NEXT:    scf.for
287  // CHECK:         // br ^bb1
288  // CHECK-NEXT:    %2 = addi
289  // CHECK-NEXT:    scf.for
290  // CHECK:         // %2 = addi
291  // CHECK: EndLiveness
292  %arg0 : index, %arg1 : index, %arg2 : index,
293  %arg3 : i32, %arg4 : i32, %arg5 : i32,
294  %buffer : memref<i32>) -> i32 {
295  %0 = addi %arg3, %arg4 : i32
296  %1 = addi %arg4, %arg5 : i32
297  scf.for %arg6 = %arg0 to %arg1 step %arg2 {
298    // CHECK: Block: 1
299    // CHECK-NEXT: LiveIn: arg5@0 arg6@0 val_7
300    // CHECK-NEXT: LiveOut:{{ *$}}
301    %2 = addi %0, %arg5 : i32
302    store %2, %buffer[] : memref<i32>
303  }
304  br ^exit
305
306^exit:
307  // CHECK: Block: 2
308  // CHECK-NEXT: LiveIn: arg0@0 arg1@0 arg2@0 arg6@0 val_7 val_8
309  // CHECK-NEXT: LiveOut:{{ *$}}
310  scf.for %arg7 = %arg0 to %arg1 step %arg2 {
311    // CHECK: Block: 3
312    // CHECK-NEXT: LiveIn: arg6@0 val_7 val_8
313    // CHECK-NEXT: LiveOut:{{ *$}}
314    %2 = addi %0, %1 : i32
315    store %2, %buffer[] : memref<i32>
316  }
317  return %1 : i32
318}
319