1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2# RUN: llc -mtriple=riscv32 -run-pass=finalize-isel -simplify-mir -o - %s \
3# RUN:  | FileCheck -check-prefix=RV32I %s
4# RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -run-pass=finalize-isel -simplify-mir -o - %s \
5# RUN:  | FileCheck -check-prefix=RV32IBT %s
6# RUN: llc -mtriple=riscv64 -run-pass=finalize-isel -simplify-mir -o - %s \
7# RUN:  | FileCheck -check-prefix=RV64I %s
8# RUN: llc -mtriple=riscv64 -mattr=+experimental-zbt -run-pass=finalize-isel -simplify-mir -o - %s \
9# RUN:  | FileCheck -check-prefix=RV64IBT %s
10
11# Provide dummy definitions of functions and just enough metadata to create a
12# DBG_VALUE.
13--- |
14  define void @cmov_interleaved_bad() {
15    ret void
16  }
17  define void @cmov_interleaved_debug_value() {
18    ret void
19  }
20...
21---
22# Here we have a sequence of select instructions with a non-select instruction
23# in the middle. Because the non-select depends on the result of a previous
24# select, we cannot optimize the sequence to share control-flow.
25name:            cmov_interleaved_bad
26alignment:       4
27tracksRegLiveness: true
28registers:
29  - { id: 0, class: gpr }
30  - { id: 1, class: gpr }
31  - { id: 2, class: gpr }
32  - { id: 3, class: gpr }
33  - { id: 4, class: gpr }
34  - { id: 5, class: gpr }
35  - { id: 6, class: gpr }
36  - { id: 7, class: gpr }
37  - { id: 8, class: gpr }
38  - { id: 9, class: gpr }
39  - { id: 10, class: gpr }
40liveins:
41  - { reg: '$x10', virtual-reg: '%0' }
42  - { reg: '$x11', virtual-reg: '%1' }
43  - { reg: '$x12', virtual-reg: '%2' }
44  - { reg: '$x13', virtual-reg: '%3' }
45body:             |
46  bb.0:
47    liveins: $x10, $x11, $x12, $x13
48
49    ; RV32I-LABEL: name: cmov_interleaved_bad
50    ; RV32I: successors: %bb.1, %bb.2
51    ; RV32I-NEXT: liveins: $x10, $x11, $x12, $x13
52    ; RV32I-NEXT: {{  $}}
53    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x13
54    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x12
55    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x11
56    ; RV32I-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10
57    ; RV32I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
58    ; RV32I-NEXT: [[COPY4:%[0-9]+]]:gpr = COPY $x0
59    ; RV32I-NEXT: BNE [[ANDI]], [[COPY4]], %bb.2
60    ; RV32I-NEXT: {{  $}}
61    ; RV32I-NEXT: .1:
62    ; RV32I-NEXT: {{  $}}
63    ; RV32I-NEXT: .2:
64    ; RV32I-NEXT: successors: %bb.3, %bb.4
65    ; RV32I-NEXT: {{  $}}
66    ; RV32I-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
67    ; RV32I-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[PHI]], 1
68    ; RV32I-NEXT: BNE [[ANDI]], [[COPY4]], %bb.4
69    ; RV32I-NEXT: {{  $}}
70    ; RV32I-NEXT: .3:
71    ; RV32I-NEXT: {{  $}}
72    ; RV32I-NEXT: .4:
73    ; RV32I-NEXT: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.2, [[COPY1]], %bb.3
74    ; RV32I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
75    ; RV32I-NEXT: $x10 = COPY [[ADD]]
76    ; RV32I-NEXT: PseudoRET implicit $x10
77    ; RV32IBT-LABEL: name: cmov_interleaved_bad
78    ; RV32IBT: successors: %bb.1, %bb.2
79    ; RV32IBT-NEXT: liveins: $x10, $x11, $x12, $x13
80    ; RV32IBT-NEXT: {{  $}}
81    ; RV32IBT-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x13
82    ; RV32IBT-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x12
83    ; RV32IBT-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x11
84    ; RV32IBT-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10
85    ; RV32IBT-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
86    ; RV32IBT-NEXT: [[COPY4:%[0-9]+]]:gpr = COPY $x0
87    ; RV32IBT-NEXT: BNE [[ANDI]], [[COPY4]], %bb.2
88    ; RV32IBT-NEXT: {{  $}}
89    ; RV32IBT-NEXT: .1:
90    ; RV32IBT-NEXT: {{  $}}
91    ; RV32IBT-NEXT: .2:
92    ; RV32IBT-NEXT: successors: %bb.3, %bb.4
93    ; RV32IBT-NEXT: {{  $}}
94    ; RV32IBT-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
95    ; RV32IBT-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[PHI]], 1
96    ; RV32IBT-NEXT: BNE [[ANDI]], [[COPY4]], %bb.4
97    ; RV32IBT-NEXT: {{  $}}
98    ; RV32IBT-NEXT: .3:
99    ; RV32IBT-NEXT: {{  $}}
100    ; RV32IBT-NEXT: .4:
101    ; RV32IBT-NEXT: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.2, [[COPY1]], %bb.3
102    ; RV32IBT-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
103    ; RV32IBT-NEXT: $x10 = COPY [[ADD]]
104    ; RV32IBT-NEXT: PseudoRET implicit $x10
105    ; RV64I-LABEL: name: cmov_interleaved_bad
106    ; RV64I: successors: %bb.1, %bb.2
107    ; RV64I-NEXT: liveins: $x10, $x11, $x12, $x13
108    ; RV64I-NEXT: {{  $}}
109    ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x13
110    ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x12
111    ; RV64I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x11
112    ; RV64I-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10
113    ; RV64I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
114    ; RV64I-NEXT: [[COPY4:%[0-9]+]]:gpr = COPY $x0
115    ; RV64I-NEXT: BNE [[ANDI]], [[COPY4]], %bb.2
116    ; RV64I-NEXT: {{  $}}
117    ; RV64I-NEXT: .1:
118    ; RV64I-NEXT: {{  $}}
119    ; RV64I-NEXT: .2:
120    ; RV64I-NEXT: successors: %bb.3, %bb.4
121    ; RV64I-NEXT: {{  $}}
122    ; RV64I-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
123    ; RV64I-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[PHI]], 1
124    ; RV64I-NEXT: BNE [[ANDI]], [[COPY4]], %bb.4
125    ; RV64I-NEXT: {{  $}}
126    ; RV64I-NEXT: .3:
127    ; RV64I-NEXT: {{  $}}
128    ; RV64I-NEXT: .4:
129    ; RV64I-NEXT: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.2, [[COPY1]], %bb.3
130    ; RV64I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
131    ; RV64I-NEXT: $x10 = COPY [[ADD]]
132    ; RV64I-NEXT: PseudoRET implicit $x10
133    ; RV64IBT-LABEL: name: cmov_interleaved_bad
134    ; RV64IBT: successors: %bb.1, %bb.2
135    ; RV64IBT-NEXT: liveins: $x10, $x11, $x12, $x13
136    ; RV64IBT-NEXT: {{  $}}
137    ; RV64IBT-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x13
138    ; RV64IBT-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x12
139    ; RV64IBT-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x11
140    ; RV64IBT-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10
141    ; RV64IBT-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
142    ; RV64IBT-NEXT: [[COPY4:%[0-9]+]]:gpr = COPY $x0
143    ; RV64IBT-NEXT: BNE [[ANDI]], [[COPY4]], %bb.2
144    ; RV64IBT-NEXT: {{  $}}
145    ; RV64IBT-NEXT: .1:
146    ; RV64IBT-NEXT: {{  $}}
147    ; RV64IBT-NEXT: .2:
148    ; RV64IBT-NEXT: successors: %bb.3, %bb.4
149    ; RV64IBT-NEXT: {{  $}}
150    ; RV64IBT-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
151    ; RV64IBT-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[PHI]], 1
152    ; RV64IBT-NEXT: BNE [[ANDI]], [[COPY4]], %bb.4
153    ; RV64IBT-NEXT: {{  $}}
154    ; RV64IBT-NEXT: .3:
155    ; RV64IBT-NEXT: {{  $}}
156    ; RV64IBT-NEXT: .4:
157    ; RV64IBT-NEXT: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.2, [[COPY1]], %bb.3
158    ; RV64IBT-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
159    ; RV64IBT-NEXT: $x10 = COPY [[ADD]]
160    ; RV64IBT-NEXT: PseudoRET implicit $x10
161    %3:gpr = COPY $x13
162    %2:gpr = COPY $x12
163    %1:gpr = COPY $x11
164    %0:gpr = COPY $x10
165    %5:gpr = ANDI %0, 1
166    %6:gpr = COPY $x0
167    %7:gpr = Select_GPR_Using_CC_GPR %5, %6, 1, %1, %2
168    %8:gpr = ADDI %7, 1
169    %9:gpr = Select_GPR_Using_CC_GPR %5, %6, 1, %3, %2
170    %10:gpr = ADD %7, killed %9
171    $x10 = COPY %10
172    PseudoRET implicit $x10
173
174...
175---
176# Demonstrate that debug info associated with selects is correctly moved to
177# the tail basic block, while debug info associated with non-selects is left
178# in the head basic block.
179name:            cmov_interleaved_debug_value
180alignment:       4
181tracksRegLiveness: true
182registers:
183  - { id: 0, class: gpr }
184  - { id: 1, class: gpr }
185  - { id: 2, class: gpr }
186  - { id: 3, class: gpr }
187  - { id: 4, class: gpr }
188  - { id: 5, class: gpr }
189  - { id: 6, class: gpr }
190  - { id: 7, class: gpr }
191  - { id: 8, class: gpr }
192  - { id: 9, class: gpr }
193  - { id: 10, class: gpr }
194liveins:
195  - { reg: '$x10', virtual-reg: '%0' }
196  - { reg: '$x11', virtual-reg: '%1' }
197  - { reg: '$x12', virtual-reg: '%2' }
198  - { reg: '$x13', virtual-reg: '%3' }
199body:             |
200  bb.0:
201    liveins: $x10, $x11, $x12, $x13
202
203    ; RV32I-LABEL: name: cmov_interleaved_debug_value
204    ; RV32I: successors: %bb.1, %bb.2
205    ; RV32I-NEXT: liveins: $x10, $x11, $x12, $x13
206    ; RV32I-NEXT: {{  $}}
207    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x13
208    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x12
209    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x11
210    ; RV32I-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10
211    ; RV32I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
212    ; RV32I-NEXT: [[COPY4:%[0-9]+]]:gpr = COPY $x0
213    ; RV32I-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[COPY3]], 1
214    ; RV32I-NEXT: DBG_VALUE [[ADDI]], $noreg
215    ; RV32I-NEXT: BNE [[ANDI]], [[COPY4]], %bb.2
216    ; RV32I-NEXT: {{  $}}
217    ; RV32I-NEXT: .1:
218    ; RV32I-NEXT: {{  $}}
219    ; RV32I-NEXT: .2:
220    ; RV32I-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
221    ; RV32I-NEXT: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.0, [[COPY1]], %bb.1
222    ; RV32I-NEXT: DBG_VALUE [[PHI]], $noreg
223    ; RV32I-NEXT: DBG_VALUE [[PHI1]], $noreg
224    ; RV32I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
225    ; RV32I-NEXT: $x10 = COPY [[ADD]]
226    ; RV32I-NEXT: PseudoRET implicit $x10
227    ; RV32IBT-LABEL: name: cmov_interleaved_debug_value
228    ; RV32IBT: successors: %bb.1, %bb.2
229    ; RV32IBT-NEXT: liveins: $x10, $x11, $x12, $x13
230    ; RV32IBT-NEXT: {{  $}}
231    ; RV32IBT-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x13
232    ; RV32IBT-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x12
233    ; RV32IBT-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x11
234    ; RV32IBT-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10
235    ; RV32IBT-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
236    ; RV32IBT-NEXT: [[COPY4:%[0-9]+]]:gpr = COPY $x0
237    ; RV32IBT-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[COPY3]], 1
238    ; RV32IBT-NEXT: DBG_VALUE [[ADDI]], $noreg
239    ; RV32IBT-NEXT: BNE [[ANDI]], [[COPY4]], %bb.2
240    ; RV32IBT-NEXT: {{  $}}
241    ; RV32IBT-NEXT: .1:
242    ; RV32IBT-NEXT: {{  $}}
243    ; RV32IBT-NEXT: .2:
244    ; RV32IBT-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
245    ; RV32IBT-NEXT: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.0, [[COPY1]], %bb.1
246    ; RV32IBT-NEXT: DBG_VALUE [[PHI]], $noreg
247    ; RV32IBT-NEXT: DBG_VALUE [[PHI1]], $noreg
248    ; RV32IBT-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
249    ; RV32IBT-NEXT: $x10 = COPY [[ADD]]
250    ; RV32IBT-NEXT: PseudoRET implicit $x10
251    ; RV64I-LABEL: name: cmov_interleaved_debug_value
252    ; RV64I: successors: %bb.1, %bb.2
253    ; RV64I-NEXT: liveins: $x10, $x11, $x12, $x13
254    ; RV64I-NEXT: {{  $}}
255    ; RV64I-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x13
256    ; RV64I-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x12
257    ; RV64I-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x11
258    ; RV64I-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10
259    ; RV64I-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
260    ; RV64I-NEXT: [[COPY4:%[0-9]+]]:gpr = COPY $x0
261    ; RV64I-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[COPY3]], 1
262    ; RV64I-NEXT: DBG_VALUE [[ADDI]], $noreg
263    ; RV64I-NEXT: BNE [[ANDI]], [[COPY4]], %bb.2
264    ; RV64I-NEXT: {{  $}}
265    ; RV64I-NEXT: .1:
266    ; RV64I-NEXT: {{  $}}
267    ; RV64I-NEXT: .2:
268    ; RV64I-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
269    ; RV64I-NEXT: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.0, [[COPY1]], %bb.1
270    ; RV64I-NEXT: DBG_VALUE [[PHI]], $noreg
271    ; RV64I-NEXT: DBG_VALUE [[PHI1]], $noreg
272    ; RV64I-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
273    ; RV64I-NEXT: $x10 = COPY [[ADD]]
274    ; RV64I-NEXT: PseudoRET implicit $x10
275    ; RV64IBT-LABEL: name: cmov_interleaved_debug_value
276    ; RV64IBT: successors: %bb.1, %bb.2
277    ; RV64IBT-NEXT: liveins: $x10, $x11, $x12, $x13
278    ; RV64IBT-NEXT: {{  $}}
279    ; RV64IBT-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x13
280    ; RV64IBT-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x12
281    ; RV64IBT-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x11
282    ; RV64IBT-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10
283    ; RV64IBT-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
284    ; RV64IBT-NEXT: [[COPY4:%[0-9]+]]:gpr = COPY $x0
285    ; RV64IBT-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI [[COPY3]], 1
286    ; RV64IBT-NEXT: DBG_VALUE [[ADDI]], $noreg
287    ; RV64IBT-NEXT: BNE [[ANDI]], [[COPY4]], %bb.2
288    ; RV64IBT-NEXT: {{  $}}
289    ; RV64IBT-NEXT: .1:
290    ; RV64IBT-NEXT: {{  $}}
291    ; RV64IBT-NEXT: .2:
292    ; RV64IBT-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
293    ; RV64IBT-NEXT: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.0, [[COPY1]], %bb.1
294    ; RV64IBT-NEXT: DBG_VALUE [[PHI]], $noreg
295    ; RV64IBT-NEXT: DBG_VALUE [[PHI1]], $noreg
296    ; RV64IBT-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
297    ; RV64IBT-NEXT: $x10 = COPY [[ADD]]
298    ; RV64IBT-NEXT: PseudoRET implicit $x10
299    %3:gpr = COPY $x13
300    %2:gpr = COPY $x12
301    %1:gpr = COPY $x11
302    %0:gpr = COPY $x10
303    %5:gpr = ANDI %0, 1
304    %6:gpr = COPY $x0
305    %7:gpr = Select_GPR_Using_CC_GPR %5, %6, 1, %1, %2
306    DBG_VALUE %7, $noreg
307    %8:gpr = ADDI %0, 1
308    DBG_VALUE %8, $noreg
309    %9:gpr = Select_GPR_Using_CC_GPR %5, %6, 1, %3, %2
310    DBG_VALUE %9, $noreg
311    %10:gpr = ADD %7, killed %9
312    $x10 = COPY %10
313    PseudoRET implicit $x10
314
315...
316---
317