1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2# RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs -run-pass=si-lower-control-flow -o - %s | FileCheck %s
3
4# Test si-lower-control-flow insertion points when other terminator
5# instructions are present besides the control flow pseudo and a
6# branch.
7
8
9# There's another terminator instruction between SI_IF and
10# S_BRANCH. The S_CBRANCH_EXECZ should be inserted immediately before
11# S_BRANCH.
12---
13name: other_terminator_sbranch_after_si_if
14tracksRegLiveness: true
15body:             |
16  ; CHECK-LABEL: name: other_terminator_sbranch_after_si_if
17  ; CHECK: bb.0:
18  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
19  ; CHECK:   liveins: $vgpr0, $vgpr1, $sgpr4_sgpr5
20  ; CHECK:   [[COPY:%[0-9]+]]:vgpr_32 = COPY killed $vgpr0
21  ; CHECK:   [[COPY1:%[0-9]+]]:sreg_64_xexec = COPY $sgpr4_sgpr5
22  ; CHECK:   [[V_CMP_EQ_U32_e64_:%[0-9]+]]:sreg_64_xexec = V_CMP_EQ_U32_e64 0, [[COPY]], implicit $exec
23  ; CHECK:   [[COPY2:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
24  ; CHECK:   [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY2]], [[V_CMP_EQ_U32_e64_]], implicit-def dead $scc
25  ; CHECK:   [[S_XOR_B64_:%[0-9]+]]:sreg_64_xexec = S_XOR_B64 [[S_AND_B64_]], [[COPY2]], implicit-def dead $scc
26  ; CHECK:   $exec = S_MOV_B64_term killed [[S_AND_B64_]]
27  ; CHECK:   [[S_MOV_B64_term:%[0-9]+]]:sreg_64_xexec = S_MOV_B64_term killed [[COPY1]], implicit $exec
28  ; CHECK:   S_CBRANCH_EXECZ %bb.1, implicit $exec
29  ; CHECK:   S_BRANCH %bb.2
30  ; CHECK: bb.1:
31  ; CHECK:   successors: %bb.2(0x80000000)
32  ; CHECK:   S_BRANCH %bb.2
33  ; CHECK: bb.2:
34  ; CHECK:   S_ENDPGM 0, implicit [[S_MOV_B64_term]]
35  bb.0:
36    successors: %bb.2, %bb.1
37    liveins: $vgpr0, $vgpr1, $sgpr4_sgpr5
38
39    %0:vgpr_32 = COPY killed $vgpr0
40    %1:sreg_64_xexec = COPY $sgpr4_sgpr5
41    %2:sreg_64_xexec = V_CMP_EQ_U32_e64 0, %0, implicit $exec
42    %3:sreg_64_xexec = SI_IF %2, %bb.1, implicit-def $exec, implicit-def dead $scc, implicit $exec
43    %4:sreg_64_xexec = S_MOV_B64_term killed %1, implicit $exec
44    S_BRANCH %bb.2
45
46  bb.1:
47    S_BRANCH %bb.2
48
49  bb.2:
50    S_ENDPGM 0, implicit %4
51
52...
53
54# S_CBRANCH_EXECZ should be inserted after the other terminator
55---
56name: other_terminator_fallthrough_after_si_if
57tracksRegLiveness: true
58body:             |
59  ; CHECK-LABEL: name: other_terminator_fallthrough_after_si_if
60  ; CHECK: bb.0:
61  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
62  ; CHECK:   liveins: $vgpr0, $vgpr1, $sgpr4_sgpr5
63  ; CHECK:   [[COPY:%[0-9]+]]:vgpr_32 = COPY killed $vgpr0
64  ; CHECK:   [[COPY1:%[0-9]+]]:sreg_64_xexec = COPY $sgpr4_sgpr5
65  ; CHECK:   [[V_CMP_EQ_U32_e64_:%[0-9]+]]:sreg_64_xexec = V_CMP_EQ_U32_e64 0, [[COPY]], implicit $exec
66  ; CHECK:   [[COPY2:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
67  ; CHECK:   [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY2]], [[V_CMP_EQ_U32_e64_]], implicit-def dead $scc
68  ; CHECK:   [[S_XOR_B64_:%[0-9]+]]:sreg_64_xexec = S_XOR_B64 [[S_AND_B64_]], [[COPY2]], implicit-def dead $scc
69  ; CHECK:   $exec = S_MOV_B64_term killed [[S_AND_B64_]]
70  ; CHECK:   [[S_MOV_B64_term:%[0-9]+]]:sreg_64_xexec = S_MOV_B64_term killed [[COPY1]], implicit $exec
71  ; CHECK:   S_CBRANCH_EXECZ %bb.2, implicit $exec
72  ; CHECK: bb.1:
73  ; CHECK:   successors: %bb.2(0x80000000)
74  ; CHECK:   S_BRANCH %bb.2
75  ; CHECK: bb.2:
76  ; CHECK:   S_ENDPGM 0, implicit [[S_MOV_B64_term]]
77  bb.0:
78    successors: %bb.2, %bb.1
79    liveins: $vgpr0, $vgpr1, $sgpr4_sgpr5
80
81    %0:vgpr_32 = COPY killed $vgpr0
82    %1:sreg_64_xexec = COPY $sgpr4_sgpr5
83    %2:sreg_64_xexec = V_CMP_EQ_U32_e64 0, %0, implicit $exec
84    %3:sreg_64_xexec = SI_IF %2, %bb.2, implicit-def $exec, implicit-def dead $scc, implicit $exec
85    %4:sreg_64_xexec = S_MOV_B64_term killed %1, implicit $exec
86
87  bb.1:
88    S_BRANCH %bb.2
89
90  bb.2:
91    S_ENDPGM 0, implicit %4
92
93...
94
95---
96name: other_terminator_sbranch_after_si_else
97tracksRegLiveness: true
98body:             |
99  ; CHECK-LABEL: name: other_terminator_sbranch_after_si_else
100  ; CHECK: bb.0:
101  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
102  ; CHECK:   liveins: $vgpr0, $vgpr1, $sgpr4_sgpr5
103  ; CHECK:   [[S_OR_SAVEEXEC_B64_:%[0-9]+]]:sreg_64 = S_OR_SAVEEXEC_B64 %2, implicit-def $exec, implicit-def $scc, implicit $exec
104  ; CHECK:   [[COPY:%[0-9]+]]:vgpr_32 = COPY killed $vgpr0
105  ; CHECK:   [[COPY1:%[0-9]+]]:sreg_64_xexec = COPY $sgpr4_sgpr5
106  ; CHECK:   [[V_CMP_EQ_U32_e64_:%[0-9]+]]:sreg_64_xexec = V_CMP_EQ_U32_e64 0, [[COPY]], implicit $exec
107  ; CHECK:   [[S_AND_B64_:%[0-9]+]]:sreg_64_xexec = S_AND_B64 $exec, [[S_OR_SAVEEXEC_B64_]], implicit-def $scc
108  ; CHECK:   $exec = S_XOR_B64_term $exec, [[S_AND_B64_]], implicit-def $scc
109  ; CHECK:   [[S_MOV_B64_term:%[0-9]+]]:sreg_64_xexec = S_MOV_B64_term killed [[COPY1]], implicit $exec
110  ; CHECK:   S_CBRANCH_EXECZ %bb.1, implicit $exec
111  ; CHECK:   S_BRANCH %bb.2
112  ; CHECK: bb.1:
113  ; CHECK:   successors: %bb.2(0x80000000)
114  ; CHECK:   S_BRANCH %bb.2
115  ; CHECK: bb.2:
116  ; CHECK:   S_ENDPGM 0, implicit [[S_MOV_B64_term]]
117  bb.0:
118    successors: %bb.2, %bb.1
119    liveins: $vgpr0, $vgpr1, $sgpr4_sgpr5
120
121    %0:vgpr_32 = COPY killed $vgpr0
122    %1:sreg_64_xexec = COPY $sgpr4_sgpr5
123    %2:sreg_64_xexec = V_CMP_EQ_U32_e64 0, %0, implicit $exec
124    %3:sreg_64_xexec = SI_ELSE %2, %bb.1, implicit-def $exec, implicit-def dead $scc, implicit $exec
125    %4:sreg_64_xexec = S_MOV_B64_term killed %1, implicit $exec
126    S_BRANCH %bb.2
127
128  bb.1:
129    S_BRANCH %bb.2
130
131  bb.2:
132    S_ENDPGM 0, implicit %4
133
134...
135
136---
137name: other_terminator_sbranch_after_si_loop
138tracksRegLiveness: true
139body:             |
140  ; CHECK-LABEL: name: other_terminator_sbranch_after_si_loop
141  ; CHECK: bb.0:
142  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
143  ; CHECK:   liveins: $vgpr0, $vgpr1, $sgpr4_sgpr5
144  ; CHECK:   [[COPY:%[0-9]+]]:vgpr_32 = COPY killed $vgpr0
145  ; CHECK:   [[COPY1:%[0-9]+]]:sreg_64_xexec = COPY $sgpr4_sgpr5
146  ; CHECK:   [[V_CMP_EQ_U32_e64_:%[0-9]+]]:sreg_64_xexec = V_CMP_EQ_U32_e64 0, [[COPY]], implicit $exec
147  ; CHECK:   $exec = S_ANDN2_B64_term $exec, [[V_CMP_EQ_U32_e64_]], implicit-def $scc
148  ; CHECK:   [[S_MOV_B64_term:%[0-9]+]]:sreg_64_xexec = S_MOV_B64_term killed [[COPY1]], implicit $exec
149  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
150  ; CHECK:   S_BRANCH %bb.2
151  ; CHECK: bb.1:
152  ; CHECK:   successors: %bb.2(0x80000000)
153  ; CHECK:   S_BRANCH %bb.2
154  ; CHECK: bb.2:
155  ; CHECK:   S_ENDPGM 0, implicit [[S_MOV_B64_term]]
156  bb.0:
157    successors: %bb.2, %bb.1
158    liveins: $vgpr0, $vgpr1, $sgpr4_sgpr5
159
160    %0:vgpr_32 = COPY killed $vgpr0
161    %1:sreg_64_xexec = COPY $sgpr4_sgpr5
162    %2:sreg_64_xexec = V_CMP_EQ_U32_e64 0, %0, implicit $exec
163    SI_LOOP %2, %bb.1, implicit-def $exec, implicit-def dead $scc, implicit $exec
164    %4:sreg_64_xexec = S_MOV_B64_term killed %1, implicit $exec
165    S_BRANCH %bb.2
166
167  bb.1:
168    S_BRANCH %bb.2
169
170  bb.2:
171    S_ENDPGM 0, implicit %4
172
173...
174
175# The save exec result register of SI_IF is used by other terminators
176# inserted to behave as a lowered phi. The output register of SI_IF
177# was ignored, and the def was removed, so the S_MOV_B64_term uses
178# would fail the verifier.
179
180---
181name:            si_if_use
182alignment:       1
183legalized:       true
184regBankSelected: true
185selected:        true
186tracksRegLiveness: true
187body:             |
188  ; CHECK-LABEL: name: si_if_use
189  ; CHECK: bb.0:
190  ; CHECK:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
191  ; CHECK:   liveins: $vgpr0, $vgpr1, $sgpr30_sgpr31
192  ; CHECK:   [[COPY:%[0-9]+]]:vgpr_32 = COPY killed $vgpr0
193  ; CHECK:   [[COPY1:%[0-9]+]]:vgpr_32 = COPY killed $vgpr1
194  ; CHECK:   [[V_CMP_EQ_U32_e64_:%[0-9]+]]:sreg_64_xexec = V_CMP_EQ_U32_e64 killed [[COPY]], killed [[COPY1]], implicit $exec
195  ; CHECK:   [[COPY2:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
196  ; CHECK:   [[S_AND_B64_:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY2]], [[V_CMP_EQ_U32_e64_]], implicit-def dead $scc
197  ; CHECK:   [[S_XOR_B64_:%[0-9]+]]:sreg_64_xexec = S_XOR_B64 [[S_AND_B64_]], [[COPY2]], implicit-def dead $scc
198  ; CHECK:   $exec = S_MOV_B64_term killed [[S_AND_B64_]]
199  ; CHECK:   [[S_MOV_B64_term:%[0-9]+]]:sreg_64_xexec = S_MOV_B64_term [[S_XOR_B64_]], implicit $exec
200  ; CHECK:   [[S_MOV_B64_term1:%[0-9]+]]:sreg_64_xexec = S_MOV_B64_term [[S_XOR_B64_]], implicit $exec
201  ; CHECK:   S_CBRANCH_EXECZ %bb.1, implicit $exec
202  ; CHECK:   S_BRANCH %bb.2
203  ; CHECK: bb.1:
204  ; CHECK:   successors: %bb.2(0x80000000)
205  ; CHECK:   [[COPY3:%[0-9]+]]:sreg_64_xexec = COPY [[S_MOV_B64_term1]]
206  ; CHECK:   dead %7:vgpr_32 = GLOBAL_LOAD_DWORD undef %8:vreg_64, 0, 0, 0, 0, implicit $exec :: (volatile load 4, addrspace 1)
207  ; CHECK:   [[COPY4:%[0-9]+]]:sreg_64_xexec = COPY [[COPY3]]
208  ; CHECK: bb.2:
209  ; CHECK:   successors: %bb.3(0x80000000)
210  ; CHECK:   [[COPY5:%[0-9]+]]:sreg_64_xexec = COPY [[COPY4]]
211  ; CHECK:   $exec = S_OR_B64_term $exec, killed [[COPY5]], implicit-def $scc
212  ; CHECK: bb.3:
213  ; CHECK:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
214  ; CHECK:   S_SLEEP 1
215  ; CHECK:   [[COPY6:%[0-9]+]]:sreg_64 = COPY $exec, implicit-def $exec
216  ; CHECK:   [[S_AND_B64_1:%[0-9]+]]:sreg_64 = S_AND_B64 [[COPY6]], [[V_CMP_EQ_U32_e64_]], implicit-def dead $scc
217  ; CHECK:   [[S_XOR_B64_1:%[0-9]+]]:sreg_64_xexec = S_XOR_B64 [[S_AND_B64_1]], [[COPY6]], implicit-def dead $scc
218  ; CHECK:   $exec = S_MOV_B64_term killed [[S_AND_B64_1]]
219  ; CHECK:   [[S_MOV_B64_term1:%[0-9]+]]:sreg_64_xexec = S_MOV_B64_term [[S_XOR_B64_1]], implicit $exec
220  ; CHECK:   [[S_MOV_B64_term2:%[0-9]+]]:sreg_64_xexec = S_MOV_B64_term [[S_XOR_B64_1]], implicit $exec
221  ; CHECK:   S_CBRANCH_EXECZ %bb.1, implicit $exec
222  ; CHECK:   S_BRANCH %bb.2
223  bb.0:
224    liveins: $vgpr0, $vgpr1, $sgpr30_sgpr31
225
226    %0:vgpr_32 = COPY killed $vgpr0
227    %1:vgpr_32 = COPY killed $vgpr1
228    %3:sreg_64_xexec = V_CMP_EQ_U32_e64 killed %0, killed %1, implicit $exec
229    %10:sreg_64_xexec = SI_IF %3, %bb.1, implicit-def $exec, implicit-def dead $scc, implicit $exec
230    %14:sreg_64_xexec = S_MOV_B64_term %10, implicit $exec
231    %13:sreg_64_xexec = S_MOV_B64_term %10, implicit $exec
232    S_BRANCH %bb.2
233
234  bb.1:
235    %11:sreg_64_xexec = COPY %13
236    dead %6:vgpr_32 = GLOBAL_LOAD_DWORD undef %8:vreg_64, 0, 0, 0, 0, implicit $exec :: (volatile load 4, addrspace 1)
237    %14:sreg_64_xexec = COPY %11
238
239  bb.2:
240    %12:sreg_64_xexec = COPY %14
241    SI_END_CF killed %12, implicit-def $exec, implicit-def dead $scc, implicit $exec
242    S_SLEEP 1
243    %9:sreg_64_xexec = SI_IF %3, %bb.1, implicit-def $exec, implicit-def dead $scc, implicit $exec
244    %14:sreg_64_xexec = S_MOV_B64_term %9, implicit $exec
245    %13:sreg_64_xexec = S_MOV_B64_term %9, implicit $exec
246    S_BRANCH %bb.2
247
248...
249