1# RUN: llc -march=amdgcn -run-pass si-fold-operands -verify-machineinstrs %s -o - | FileCheck -check-prefix=GCN %s
2
3# GCN-LABEL: name: fold-imm-readfirstlane{{$}}
4# GCN: %1:sreg_32_xm0 = S_MOV_B32 123
5---
6name: fold-imm-readfirstlane
7tracksRegLiveness: true
8body:             |
9  bb.0:
10    %0:vgpr_32 = V_MOV_B32_e32 123, implicit $exec
11    %1:sreg_32_xm0 = V_READFIRSTLANE_B32 %0, implicit $exec
12...
13
14# GCN-LABEL: name: fold-imm-readfirstlane-readfirstlane{{$}}
15# GCN: %0:vgpr_32 = V_MOV_B32_e32 123, implicit $exec
16# GCN: %1:sreg_32_xm0 = S_MOV_B32 123
17# GCN: %2:vgpr_32 = V_MOV_B32_e32 123, implicit $exec
18# GCN: %3:sreg_32_xm0 = COPY %1
19
20---
21name: fold-imm-readfirstlane-readfirstlane
22tracksRegLiveness: true
23body:             |
24  bb.0:
25    %0:vgpr_32 = V_MOV_B32_e32 123, implicit $exec
26    %1:sreg_32_xm0 = V_READFIRSTLANE_B32 %0, implicit $exec
27    %2:vgpr_32 = COPY %1
28    %3:sreg_32_xm0 = V_READFIRSTLANE_B32 %2, implicit $exec
29
30...
31
32
33# GCN-LABEL: name: fold-copy-readfirstlane{{$}}
34# GCN: %0:sreg_32_xm0 = COPY $sgpr10
35# GCN: %1:vgpr_32 = COPY %0
36# GCN: %2:sreg_32_xm0 = COPY %0
37---
38name: fold-copy-readfirstlane
39tracksRegLiveness: true
40body:             |
41  bb.0:
42    liveins: $sgpr10
43    %0:sreg_32_xm0 = COPY $sgpr10
44    %1:vgpr_32 = COPY %0
45    %2:sreg_32_xm0 = V_READFIRSTLANE_B32 %1, implicit $exec
46
47...
48
49# GCN-LABEL: name: no-fold-copy-readfirstlane-physreg0{{$}}
50# GCN: %0:vgpr_32 = COPY $sgpr10
51# GCN-NEXT: %1:sreg_32_xm0 = V_READFIRSTLANE_B32 %0, implicit $exec
52---
53name: no-fold-copy-readfirstlane-physreg0
54tracksRegLiveness: true
55body:             |
56  bb.0:
57    liveins: $sgpr10
58    %0:vgpr_32 = COPY $sgpr10
59    %1:sreg_32_xm0 = V_READFIRSTLANE_B32 %0, implicit $exec
60
61...
62
63# GCN-LABEL: name: no-fold-copy-readfirstlane-physreg1{{$}}
64# GCN: $vgpr0 = COPY $sgpr10
65# GCN-NEXT: %0:sreg_32_xm0 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
66---
67name: no-fold-copy-readfirstlane-physreg1
68tracksRegLiveness: true
69body:             |
70  bb.0:
71    liveins: $sgpr10
72    $vgpr0 = COPY $sgpr10
73    %0:sreg_32_xm0 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
74
75...
76
77# GCN-LABEL: name: no-fold-imm-readfirstlane-physreg{{$}}
78# GCN: $vgpr0 = V_MOV_B32_e32 123, implicit $exec
79# GCN-NEXT: V_READFIRSTLANE_B32 $vgpr0, implicit $exec
80
81---
82name: no-fold-imm-readfirstlane-physreg
83tracksRegLiveness: true
84body:             |
85  bb.0:
86    $vgpr0 = V_MOV_B32_e32 123, implicit $exec
87    %0:sreg_32_xm0 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
88...
89
90# TODO: This could be folded, if the search for exec modifications was
91# smarter.
92
93# GCN-LABEL: name: fold-imm-readfirstlane-cross-block{{$}}
94# GCN: V_MOV_B32
95# GCN: V_READFIRSTLANE_B32
96---
97name: fold-imm-readfirstlane-cross-block
98tracksRegLiveness: true
99body:             |
100  bb.0:
101    %0:vgpr_32 = V_MOV_B32_e32 123, implicit $exec
102
103  bb.1:
104    %1:sreg_32_xm0 = V_READFIRSTLANE_B32 %0, implicit $exec
105...
106
107# TODO: This could be folded, if the search for exec modifications was
108# smarter.
109
110# GCN-LABEL: name: fold-copy-readfirstlane-cross-block{{$}}
111# GCN: V_MOV_B32
112# GCN: V_READFIRSTLANE_B32
113---
114name: fold-copy-readfirstlane-cross-block
115tracksRegLiveness: true
116body:             |
117  bb.0:
118    liveins: $sgpr12
119    %0:sreg_32_xm0 = COPY $sgpr12
120    %1:vgpr_32 = V_MOV_B32_e32 %0, implicit $exec
121
122  bb.1:
123    %2:sreg_32_xm0 = V_READFIRSTLANE_B32 %1, implicit $exec
124...
125
126# GCN-LABEL: name: fold-copy-readfirstlane-cross-block-exec-def{{$}}
127# GCN: V_MOV_B32
128# GCN: $exec = S_MOV_B64_term
129# GCN: V_READFIRSTLANE_B32
130---
131name: fold-copy-readfirstlane-cross-block-exec-def
132tracksRegLiveness: true
133body:             |
134  bb.0:
135    liveins: $sgpr10_sgpr11, $sgpr12
136    %0:sreg_32_xm0 = COPY $sgpr12
137    %1:vgpr_32 = V_MOV_B32_e32 %0, implicit $exec
138    $exec = S_MOV_B64_term $sgpr10_sgpr11
139
140  bb.1:
141    %2:sreg_32_xm0 = V_READFIRSTLANE_B32 %1, implicit $exec
142...
143
144# GCN-LABEL: name: fold-copy-readfirstlane-same-block-exec-def{{$}}
145# GCN: COPY
146# GCN-NEXT: %1:vgpr_32 = COPY %0
147# GCN-NEXT: $exec = S_MOV_B64
148# GCN-NEXT: V_READFIRSTLANE_B32
149---
150name: fold-copy-readfirstlane-same-block-exec-def
151tracksRegLiveness: true
152body:             |
153  bb.0:
154    liveins: $sgpr10_sgpr11, $sgpr12
155    %0:sreg_32_xm0 = COPY $sgpr12
156    %1:vgpr_32 = COPY %0, implicit $exec
157    $exec = S_MOV_B64 $sgpr10_sgpr11
158    %2:sreg_32_xm0 = V_READFIRSTLANE_B32 %1, implicit $exec
159
160...
161
162# GCN-LABEL: name: fold-imm-readfirstlane-cross-block-exec-def{{$}}
163# GCN: V_MOV_B32
164# GCN: $exec = S_MOV_B64
165# GCN: V_READFIRSTLANE_B32
166
167---
168name: fold-imm-readfirstlane-cross-block-exec-def
169tracksRegLiveness: true
170body:             |
171  bb.0:
172    liveins: $sgpr10_sgpr11, $sgpr12_sgpr13
173    %0:vgpr_32 = V_MOV_B32_e32 123, implicit $exec
174    $exec = S_MOV_B64_term $sgpr10_sgpr11
175
176  bb.1:
177    %1:sreg_32_xm0 = V_READFIRSTLANE_B32 %0, implicit $exec
178...
179
180# GCN-LABEL: name: fold-imm-readfirstlane-same-block-exec-def{{$}}
181# GCN: V_MOV_B32
182# GCN-NEXT: $exec = S_MOV_B64
183# GCN-NEXT: V_READFIRSTLANE_B32
184---
185name: fold-imm-readfirstlane-same-block-exec-def
186tracksRegLiveness: true
187body:             |
188  bb.0:
189    liveins: $sgpr10_sgpr11
190    %0:vgpr_32 = V_MOV_B32_e32 123, implicit $exec
191    $exec = S_MOV_B64 $sgpr10_sgpr11
192    %1:sreg_32_xm0 = V_READFIRSTLANE_B32 %0, implicit $exec
193
194...
195
196# GCN-LABEL: name: fold-sgpr-copy-readfirstlane-same-block-exec-def{{$}}
197# GCN: COPY
198# GCN-NEXT: $exec = S_MOV_B64
199# GCN-NEXT: V_READFIRSTLANE_B32
200---
201name: fold-sgpr-copy-readfirstlane-same-block-exec-def
202tracksRegLiveness: true
203body:             |
204  bb.0:
205    liveins: $sgpr10_sgpr11, $sgpr12
206    %0:vgpr_32 = COPY $sgpr12
207    $exec = S_MOV_B64 $sgpr10_sgpr11
208    %1:sreg_32_xm0 = V_READFIRSTLANE_B32 %0, implicit $exec
209...
210
211# GCN-LABEL: name: fold-imm-readfirstlane-user{{$}}
212# GCN: %3:sreg_32_xm0 = S_MOV_B32 123
213---
214name: fold-imm-readfirstlane-user
215tracksRegLiveness: true
216body:             |
217  bb.0:
218    liveins: $vgpr0, $sgpr0_sgpr1
219    %0:vgpr_32 = V_MOV_B32_e32 123, implicit $exec
220    %1:sreg_32_xm0 = V_READFIRSTLANE_B32 %0, implicit $exec
221    %2:sreg_32_xm0 = COPY %1
222    %3:sreg_32_xm0 = COPY %2
223    S_ENDPGM 0, implicit %3
224...
225
226# GCN-LABEL: name: fold-imm-readlane{{$}}
227# GCN: %1:sreg_32_xm0 = S_MOV_B32 123
228---
229name: fold-imm-readlane
230tracksRegLiveness: true
231body:             |
232  bb.0:
233    liveins: $vgpr0, $sgpr0_sgpr1
234    %0:vgpr_32 = V_MOV_B32_e32 123, implicit $exec
235    %1:sreg_32_xm0 = V_READLANE_B32 %0, 0, implicit $exec
236...
237
238# GCN-LABEL: name: fold-imm-readlane-src1{{$}}
239# GCN: %0:vgpr_32 = COPY $vgpr0
240# GCN: V_READLANE_B32 %0, 12, implicit $exec
241---
242name: fold-imm-readlane-src1
243tracksRegLiveness: true
244body:             |
245  bb.0:
246    liveins: $vgpr0
247    %0:vgpr_32 = COPY $vgpr0
248    %1:sreg_32_xm0 = S_MOV_B32 12
249    %2:sreg_32_xm0 = V_READLANE_B32 %0, %1, implicit $exec
250...
251
252# Constant for subreg0
253# GCN-LABEL: name: fold-imm-readfirstlane-regsequence0{{$}}
254
255# GCN: %0:vgpr_32 = COPY $vgpr0
256# GCN-NEXT: %1:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
257# GCN-NEXT: %2:vreg_64 = REG_SEQUENCE %0, %subreg.sub0, killed %1, %subreg.sub1
258# GCN-NEXT: %3:sgpr_32 = V_READFIRSTLANE_B32 %2.sub0, implicit $exec
259# GCN-NEXT: %4:sgpr_32 = S_MOV_B32 0
260---
261name: fold-imm-readfirstlane-regsequence0
262tracksRegLiveness: true
263body:             |
264  bb.0:
265    liveins: $vgpr0
266    %0:vgpr_32 = COPY $vgpr0
267    %1:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
268    %2:vreg_64 = REG_SEQUENCE %0:vgpr_32, %subreg.sub0, killed %1:vgpr_32, %subreg.sub1
269    %3:sgpr_32 = V_READFIRSTLANE_B32 %2.sub0:vreg_64, implicit $exec
270    %4:sgpr_32 = V_READFIRSTLANE_B32 %2.sub1:vreg_64, implicit $exec
271...
272
273# Constant for subreg1
274# GCN-LABEL: name: fold-imm-readfirstlane-regsequence1{{$}}
275# GCN: %0:vgpr_32 = COPY $vgpr0
276# GCN-NEXT: %1:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
277# GCN-NEXT: %2:vreg_64 = REG_SEQUENCE %1, %subreg.sub0, killed %0, %subreg.sub1
278# GCN-NEXT: %3:sgpr_32 = S_MOV_B32 0
279# GCN-NEXT: %4:sgpr_32 = V_READFIRSTLANE_B32 %2.sub1, implicit $exec
280
281---
282name: fold-imm-readfirstlane-regsequence1
283tracksRegLiveness: true
284body:             |
285  bb.0:
286    liveins: $vgpr0
287    %0:vgpr_32 = COPY $vgpr0
288    %1:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
289    %2:vreg_64 = REG_SEQUENCE %1:vgpr_32, %subreg.sub0, killed %0:vgpr_32, %subreg.sub1
290    %3:sgpr_32 = V_READFIRSTLANE_B32 %2.sub0:vreg_64, implicit $exec
291    %4:sgpr_32 = V_READFIRSTLANE_B32 %2.sub1:vreg_64, implicit $exec
292...
293
294# Different constant regs for each subreg
295# GCN-LABEL: name: fold-imm-readfirstlane-regsequence2{{$}}
296# GCN: %0:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
297# GCN-NEXT: %1:vgpr_32 = V_MOV_B32_e32 1, implicit $exec
298# GCN-NEXT: %2:vreg_64 = REG_SEQUENCE %0, %subreg.sub0, killed %1, %subreg.sub1
299# GCN-NEXT: %3:sgpr_32 = S_MOV_B32 0
300# GCN-NEXT: %4:sgpr_32 = S_MOV_B32 1
301---
302name: fold-imm-readfirstlane-regsequence2
303tracksRegLiveness: true
304body:             |
305  bb.0:
306    %0:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
307    %1:vgpr_32 = V_MOV_B32_e32 1, implicit $exec
308    %2:vreg_64 = REG_SEQUENCE %0:vgpr_32, %subreg.sub0, killed %1:vgpr_32, %subreg.sub1
309    %3:sgpr_32 = V_READFIRSTLANE_B32 %2.sub0:vreg_64, implicit $exec
310    %4:sgpr_32 = V_READFIRSTLANE_B32 %2.sub1:vreg_64, implicit $exec
311...
312
313# Same constant reg for each subreg, so there are multiple constant uses
314# GCN-LABEL: name: fold-imm-readfirstlane-regsequence3{{$}}
315# GCN: %0:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
316# GCN-NEXT: %1:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
317# GCN-NEXT: %2:vreg_64 = REG_SEQUENCE %0, %subreg.sub0, killed %1, %subreg.sub1
318# GCN-NEXT: %3:sgpr_32 = S_MOV_B32 0
319# GCN-NEXT: %4:sgpr_32 = S_MOV_B32 0
320---
321name: fold-imm-readfirstlane-regsequence3
322tracksRegLiveness: true
323body:             |
324  bb.0:
325    %0:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
326    %1:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
327    %2:vreg_64 = REG_SEQUENCE %0:vgpr_32, %subreg.sub0, killed %1:vgpr_32, %subreg.sub1
328    %3:sgpr_32 = V_READFIRSTLANE_B32 %2.sub0:vreg_64, implicit $exec
329    %4:sgpr_32 = V_READFIRSTLANE_B32 %2.sub1:vreg_64, implicit $exec
330...
331
332# FIXME: This should fold
333# GCN-LABEL: name: fold-copy-readfirstlane-regsequence0{{$}}
334# GCN: %0:vgpr_32 = COPY $sgpr10
335# GCN-NEXT: %1:vgpr_32 = COPY $sgpr11
336# GCN-NEXT: %2:vreg_64 = REG_SEQUENCE %0, %subreg.sub0, killed %1, %subreg.sub1
337# GCN-NEXT: %3:sgpr_32 = V_READFIRSTLANE_B32 %2.sub0, implicit $exec
338# GCN-NEXT: %4:sgpr_32 = V_READFIRSTLANE_B32 %2.sub1, implicit $exec
339---
340name: fold-copy-readfirstlane-regsequence0
341tracksRegLiveness: true
342body:             |
343  bb.0:
344    liveins: $sgpr10, $sgpr11
345    %0:vgpr_32 = COPY $sgpr10
346    %1:vgpr_32 = COPY $sgpr11
347    %2:vreg_64 = REG_SEQUENCE %0:vgpr_32, %subreg.sub0, killed %1:vgpr_32, %subreg.sub1
348    %3:sgpr_32 = V_READFIRSTLANE_B32 %2.sub0:vreg_64, implicit $exec
349    %4:sgpr_32 = V_READFIRSTLANE_B32 %2.sub1:vreg_64, implicit $exec
350...
351
352# GCN-LABEL: name: fold-copy-readfirstlane-regsequence1{{$}}
353# GCN: %0:sreg_32_xm0 = COPY $sgpr10
354# GCN-NEXT: %1:sreg_32_xm0 = COPY $sgpr11
355# GCN-NEXT: %2:vgpr_32 = COPY %0
356# GCN-NEXT: %3:vgpr_32 = COPY %1
357# GCN-NEXT: %4:vreg_64 = REG_SEQUENCE %2, %subreg.sub0, killed %3, %subreg.sub1
358# GCN-NEXT: %5:sgpr_32 = V_READFIRSTLANE_B32 %4.sub0, implicit $exec
359# GCN-NEXT: %6:sgpr_32 = V_READFIRSTLANE_B32 %4.sub1, implicit $exec
360---
361name: fold-copy-readfirstlane-regsequence1
362tracksRegLiveness: true
363body:             |
364  bb.0:
365    liveins: $sgpr10, $sgpr11
366    %0:sreg_32_xm0 = COPY $sgpr10
367    %1:sreg_32_xm0 = COPY $sgpr11
368    %2:vgpr_32 = COPY %0
369    %3:vgpr_32 = COPY %1
370    %4:vreg_64 = REG_SEQUENCE %2:vgpr_32, %subreg.sub0, killed %3:vgpr_32, %subreg.sub1
371    %5:sgpr_32 = V_READFIRSTLANE_B32 %4.sub0:vreg_64, implicit $exec
372    %6:sgpr_32 = V_READFIRSTLANE_B32 %4.sub1:vreg_64, implicit $exec
373...
374