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=riscv64 -run-pass=finalize-isel -simplify-mir -o - %s \
5# RUN:  | FileCheck -check-prefix=RV64I %s
6
7# Provide dummy definitions of functions and just enough metadata to create a
8# DBG_VALUE.
9--- |
10  define void @cmov_interleaved_bad() {
11    ret void
12  }
13  define void @cmov_interleaved_debug_value() {
14    ret void
15  }
16  !1 = !DIExpression()
17...
18---
19# Here we have a sequence of select instructions with a non-select instruction
20# in the middle. Because the non-select depends on the result of a previous
21# select, we cannot optimize the sequence to share control-flow.
22name:            cmov_interleaved_bad
23alignment:       2
24tracksRegLiveness: true
25registers:
26  - { id: 0, class: gpr }
27  - { id: 1, class: gpr }
28  - { id: 2, class: gpr }
29  - { id: 3, class: gpr }
30  - { id: 4, class: gpr }
31  - { id: 5, class: gpr }
32  - { id: 6, class: gpr }
33  - { id: 7, class: gpr }
34  - { id: 8, class: gpr }
35  - { id: 9, class: gpr }
36  - { id: 10, class: gpr }
37liveins:
38  - { reg: '$x10', virtual-reg: '%0' }
39  - { reg: '$x11', virtual-reg: '%1' }
40  - { reg: '$x12', virtual-reg: '%2' }
41  - { reg: '$x13', virtual-reg: '%3' }
42body:             |
43  bb.0:
44    liveins: $x10, $x11, $x12, $x13
45
46    ; RV32I-LABEL: name: cmov_interleaved_bad
47    ; RV32I: successors: %bb.1, %bb.2
48    ; RV32I: liveins: $x10, $x11, $x12, $x13
49    ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x13
50    ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x12
51    ; RV32I: [[COPY2:%[0-9]+]]:gpr = COPY $x11
52    ; RV32I: [[COPY3:%[0-9]+]]:gpr = COPY $x10
53    ; RV32I: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
54    ; RV32I: [[COPY4:%[0-9]+]]:gpr = COPY $x0
55    ; RV32I: BNE [[ANDI]], [[COPY4]], %bb.2
56    ; RV32I: .1:
57    ; RV32I: .2:
58    ; RV32I: successors: %bb.3, %bb.4
59    ; RV32I: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
60    ; RV32I: [[ADDI:%[0-9]+]]:gpr = ADDI [[PHI]], 1
61    ; RV32I: BNE [[ANDI]], [[COPY4]], %bb.4
62    ; RV32I: .3:
63    ; RV32I: .4:
64    ; RV32I: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.2, [[COPY1]], %bb.3
65    ; RV32I: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
66    ; RV32I: $x10 = COPY [[ADD]]
67    ; RV32I: PseudoRET implicit $x10
68    ; RV64I-LABEL: name: cmov_interleaved_bad
69    ; RV64I: successors: %bb.1, %bb.2
70    ; RV64I: liveins: $x10, $x11, $x12, $x13
71    ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x13
72    ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x12
73    ; RV64I: [[COPY2:%[0-9]+]]:gpr = COPY $x11
74    ; RV64I: [[COPY3:%[0-9]+]]:gpr = COPY $x10
75    ; RV64I: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
76    ; RV64I: [[COPY4:%[0-9]+]]:gpr = COPY $x0
77    ; RV64I: BNE [[ANDI]], [[COPY4]], %bb.2
78    ; RV64I: .1:
79    ; RV64I: .2:
80    ; RV64I: successors: %bb.3, %bb.4
81    ; RV64I: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
82    ; RV64I: [[ADDI:%[0-9]+]]:gpr = ADDI [[PHI]], 1
83    ; RV64I: BNE [[ANDI]], [[COPY4]], %bb.4
84    ; RV64I: .3:
85    ; RV64I: .4:
86    ; RV64I: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.2, [[COPY1]], %bb.3
87    ; RV64I: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
88    ; RV64I: $x10 = COPY [[ADD]]
89    ; RV64I: PseudoRET implicit $x10
90    %3:gpr = COPY $x13
91    %2:gpr = COPY $x12
92    %1:gpr = COPY $x11
93    %0:gpr = COPY $x10
94    %5:gpr = ANDI %0, 1
95    %6:gpr = COPY $x0
96    %7:gpr = Select_GPR_Using_CC_GPR %5, %6, 22, %1, %2
97    %8:gpr = ADDI %7, 1
98    %9:gpr = Select_GPR_Using_CC_GPR %5, %6, 22, %3, %2
99    %10:gpr = ADD %7, killed %9
100    $x10 = COPY %10
101    PseudoRET implicit $x10
102
103...
104---
105# Demonstrate that debug info associated with selects is correctly moved to
106# the tail basic block, while debug info associated with non-selects is left
107# in the head basic block.
108name:            cmov_interleaved_debug_value
109alignment:       2
110tracksRegLiveness: true
111registers:
112  - { id: 0, class: gpr }
113  - { id: 1, class: gpr }
114  - { id: 2, class: gpr }
115  - { id: 3, class: gpr }
116  - { id: 4, class: gpr }
117  - { id: 5, class: gpr }
118  - { id: 6, class: gpr }
119  - { id: 7, class: gpr }
120  - { id: 8, class: gpr }
121  - { id: 9, class: gpr }
122  - { id: 10, class: gpr }
123liveins:
124  - { reg: '$x10', virtual-reg: '%0' }
125  - { reg: '$x11', virtual-reg: '%1' }
126  - { reg: '$x12', virtual-reg: '%2' }
127  - { reg: '$x13', virtual-reg: '%3' }
128body:             |
129  bb.0:
130    liveins: $x10, $x11, $x12, $x13
131
132    ; RV32I-LABEL: name: cmov_interleaved_debug_value
133    ; RV32I: successors: %bb.1, %bb.2
134    ; RV32I: liveins: $x10, $x11, $x12, $x13
135    ; RV32I: [[COPY:%[0-9]+]]:gpr = COPY $x13
136    ; RV32I: [[COPY1:%[0-9]+]]:gpr = COPY $x12
137    ; RV32I: [[COPY2:%[0-9]+]]:gpr = COPY $x11
138    ; RV32I: [[COPY3:%[0-9]+]]:gpr = COPY $x10
139    ; RV32I: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
140    ; RV32I: [[COPY4:%[0-9]+]]:gpr = COPY $x0
141    ; RV32I: [[ADDI:%[0-9]+]]:gpr = ADDI [[COPY3]], 1
142    ; RV32I: DBG_VALUE [[ADDI]], $noreg, !DIExpression(), !DIExpression()
143    ; RV32I: BNE [[ANDI]], [[COPY4]], %bb.2
144    ; RV32I: .1:
145    ; RV32I: .2:
146    ; RV32I: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
147    ; RV32I: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.0, [[COPY1]], %bb.1
148    ; RV32I: DBG_VALUE [[PHI]], $noreg, !DIExpression(), !DIExpression()
149    ; RV32I: DBG_VALUE [[PHI1]], $noreg, !DIExpression(), !DIExpression()
150    ; RV32I: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
151    ; RV32I: $x10 = COPY [[ADD]]
152    ; RV32I: PseudoRET implicit $x10
153    ; RV64I-LABEL: name: cmov_interleaved_debug_value
154    ; RV64I: successors: %bb.1, %bb.2
155    ; RV64I: liveins: $x10, $x11, $x12, $x13
156    ; RV64I: [[COPY:%[0-9]+]]:gpr = COPY $x13
157    ; RV64I: [[COPY1:%[0-9]+]]:gpr = COPY $x12
158    ; RV64I: [[COPY2:%[0-9]+]]:gpr = COPY $x11
159    ; RV64I: [[COPY3:%[0-9]+]]:gpr = COPY $x10
160    ; RV64I: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
161    ; RV64I: [[COPY4:%[0-9]+]]:gpr = COPY $x0
162    ; RV64I: [[ADDI:%[0-9]+]]:gpr = ADDI [[COPY3]], 1
163    ; RV64I: DBG_VALUE [[ADDI]], $noreg, !DIExpression(), !DIExpression()
164    ; RV64I: BNE [[ANDI]], [[COPY4]], %bb.2
165    ; RV64I: .1:
166    ; RV64I: .2:
167    ; RV64I: [[PHI:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.0, [[COPY1]], %bb.1
168    ; RV64I: [[PHI1:%[0-9]+]]:gpr = PHI [[COPY]], %bb.0, [[COPY1]], %bb.1
169    ; RV64I: DBG_VALUE [[PHI]], $noreg, !DIExpression(), !DIExpression()
170    ; RV64I: DBG_VALUE [[PHI1]], $noreg, !DIExpression(), !DIExpression()
171    ; RV64I: [[ADD:%[0-9]+]]:gpr = ADD [[PHI]], killed [[PHI1]]
172    ; RV64I: $x10 = COPY [[ADD]]
173    ; RV64I: PseudoRET implicit $x10
174    %3:gpr = COPY $x13
175    %2:gpr = COPY $x12
176    %1:gpr = COPY $x11
177    %0:gpr = COPY $x10
178    %5:gpr = ANDI %0, 1
179    %6:gpr = COPY $x0
180    %7:gpr = Select_GPR_Using_CC_GPR %5, %6, 22, %1, %2
181    DBG_VALUE %7, $noreg, !1, !1
182    %8:gpr = ADDI %0, 1
183    DBG_VALUE %8, $noreg, !1, !1
184    %9:gpr = Select_GPR_Using_CC_GPR %5, %6, 22, %3, %2
185    DBG_VALUE %9, $noreg, !1, !1
186    %10:gpr = ADD %7, killed %9
187    $x10 = COPY %10
188    PseudoRET implicit $x10
189
190...
191---
192