1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2# RUN: llc -O0 -mtriple=amdgcn-mesa-mesa3d -mcpu=tahiti -run-pass=legalizer -global-isel-abort=0 %s -o - | FileCheck %s
3
4---
5name: extract_s32_merge_s64_s32_s32_offset0
6
7body: |
8  bb.0:
9    ; CHECK-LABEL: name: extract_s32_merge_s64_s32_s32_offset0
10    ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
11    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[C]](s32)
12    ; CHECK: $vgpr0 = COPY [[COPY]](s32)
13    %0:_(s32) = G_CONSTANT i32 0
14    %1:_(s32) = G_CONSTANT i32 1
15    %2:_(s64) = G_MERGE_VALUES %0, %1
16    %3:_(s32) = G_EXTRACT %2, 0
17    $vgpr0 = COPY %3
18...
19
20---
21name: extract_s32_merge_s64_s32_s32_offset32
22
23body: |
24  bb.0:
25    ; CHECK-LABEL: name: extract_s32_merge_s64_s32_s32_offset32
26    ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
27    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[C]](s32)
28    ; CHECK: $vgpr0 = COPY [[COPY]](s32)
29    %0:_(s32) = G_CONSTANT i32 0
30    %1:_(s32) = G_CONSTANT i32 1
31    %2:_(s64) = G_MERGE_VALUES %0, %1
32    %3:_(s32) = G_EXTRACT %2, 32
33    $vgpr0 = COPY %3
34...
35
36---
37name: extract_s64_merge_s128_s64_s64_offset0
38
39body: |
40  bb.0:
41    ; CHECK-LABEL: name: extract_s64_merge_s128_s64_s64_offset0
42    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
43    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY [[C]](s64)
44    ; CHECK: $vgpr0_vgpr1 = COPY [[COPY]](s64)
45    %0:_(s64) = G_CONSTANT i64 0
46    %1:_(s64) = G_CONSTANT i64 1
47    %2:_(s128) = G_MERGE_VALUES %0, %1
48    %3:_(s64) = G_EXTRACT %2, 0
49    $vgpr0_vgpr1 = COPY %3
50...
51
52---
53name: extract_s64_merge_s128_s64_s64_offset64
54
55body: |
56  bb.0:
57    ; CHECK-LABEL: name: extract_s64_merge_s128_s64_s64_offset64
58    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
59    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY [[C]](s64)
60    ; CHECK: $vgpr0_vgpr1 = COPY [[COPY]](s64)
61    %0:_(s64) = G_CONSTANT i64 0
62    %1:_(s64) = G_CONSTANT i64 1
63    %2:_(s128) = G_MERGE_VALUES %0, %1
64    %3:_(s64) = G_EXTRACT %2, 64
65    $vgpr0_vgpr1 = COPY %3
66...
67
68---
69name: extract_s32_merge_s128_s64_s64_offset0
70
71body: |
72  bb.0:
73    ; CHECK-LABEL: name: extract_s32_merge_s128_s64_s64_offset0
74    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
75    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[C]](s64), 0
76    ; CHECK: $vgpr0 = COPY [[EXTRACT]](s32)
77    %0:_(s64) = G_CONSTANT i64 0
78    %1:_(s64) = G_CONSTANT i64 1
79    %2:_(s128) = G_MERGE_VALUES %0, %1
80    %3:_(s32) = G_EXTRACT %2, 0
81    $vgpr0 = COPY %3
82...
83
84---
85name: extract_s32_merge_s128_s64_s64_offset32
86
87body: |
88  bb.0:
89    ; CHECK-LABEL: name: extract_s32_merge_s128_s64_s64_offset32
90    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
91    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[C]](s64), 32
92    ; CHECK: $vgpr0 = COPY [[EXTRACT]](s32)
93    %0:_(s64) = G_CONSTANT i64 0
94    %1:_(s64) = G_CONSTANT i64 1
95    %2:_(s128) = G_MERGE_VALUES %0, %1
96    %3:_(s32) = G_EXTRACT %2, 32
97    $vgpr0 = COPY %3
98...
99
100---
101name: extract_s32_merge_s128_s64_s64_offset64
102
103body: |
104  bb.0:
105    ; CHECK-LABEL: name: extract_s32_merge_s128_s64_s64_offset64
106    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
107    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[C]](s64), 0
108    ; CHECK: $vgpr0 = COPY [[EXTRACT]](s32)
109    %0:_(s64) = G_CONSTANT i64 0
110    %1:_(s64) = G_CONSTANT i64 1
111    %2:_(s128) = G_MERGE_VALUES %0, %1
112    %3:_(s32) = G_EXTRACT %2, 64
113    $vgpr0 = COPY %3
114...
115
116---
117name: extract_s32_merge_s128_s64_s64_offset96
118
119body: |
120  bb.0:
121    ; CHECK-LABEL: name: extract_s32_merge_s128_s64_s64_offset96
122    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
123    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[C]](s64), 32
124    ; CHECK: $vgpr0 = COPY [[EXTRACT]](s32)
125    %0:_(s64) = G_CONSTANT i64 0
126    %1:_(s64) = G_CONSTANT i64 1
127    %2:_(s128) = G_MERGE_VALUES %0, %1
128    %3:_(s32) = G_EXTRACT %2, 96
129    $vgpr0 = COPY %3
130...
131
132# Destination size fits, but is skewed from the start of the register.
133---
134name: extract_s16_merge_s128_s64_s64_offset18
135
136body: |
137  bb.0:
138    ; CHECK-LABEL: name: extract_s16_merge_s128_s64_s64_offset18
139    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
140    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s16) = G_EXTRACT [[C]](s64), 18
141    ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[EXTRACT]](s16)
142    ; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
143    %0:_(s64) = G_CONSTANT i64 0
144    %1:_(s64) = G_CONSTANT i64 1
145    %2:_(s128) = G_MERGE_VALUES %0, %1
146    %3:_(s16) = G_EXTRACT %2, 18
147    %4:_(s32) = G_ANYEXT %3
148    $vgpr0 = COPY %4
149...
150
151# Destination size fits, but is skewed from the start of the register.
152---
153name: extract_s16_merge_s128_s64_s64_offset82
154
155body: |
156  bb.0:
157    ; CHECK-LABEL: name: extract_s16_merge_s128_s64_s64_offset82
158    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
159    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s16) = G_EXTRACT [[C]](s64), 18
160    ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[EXTRACT]](s16)
161    ; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
162    %0:_(s64) = G_CONSTANT i64 0
163    %1:_(s64) = G_CONSTANT i64 1
164    %2:_(s128) = G_MERGE_VALUES %0, %1
165    %3:_(s16) = G_EXTRACT %2, 82
166    %4:_(s32) = G_ANYEXT %3
167    $vgpr0 = COPY %4
168...
169
170
171# Can't handle this since it spans two registers
172---
173name: extract_s64_merge_s128_s64_s64_offset32
174
175body: |
176  bb.0:
177    ; CHECK-LABEL: name: extract_s64_merge_s128_s64_s64_offset32
178    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
179    ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
180    ; CHECK: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[C]](s64), [[C1]](s64)
181    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s64) = G_EXTRACT [[MV]](s128), 32
182    ; CHECK: $vgpr0_vgpr1 = COPY [[EXTRACT]](s64)
183    %0:_(s64) = G_CONSTANT i64 0
184    %1:_(s64) = G_CONSTANT i64 1
185    %2:_(s128) = G_MERGE_VALUES %0, %1
186    %3:_(s64) = G_EXTRACT %2, 32
187    $vgpr0_vgpr1 = COPY %3
188...
189
190
191# Only the last bit spans to another register
192---
193name: extract_s16_merge_s32_s32_offset1
194
195body: |
196  bb.0:
197    ; CHECK-LABEL: name: extract_s16_merge_s32_s32_offset1
198    ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
199    ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
200    ; CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[C]](s32), [[C1]](s32)
201    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[MV]](s64), 1
202    ; CHECK: $vgpr0 = COPY [[EXTRACT]](s32)
203    %0:_(s32) = G_CONSTANT i32 0
204    %1:_(s32) = G_CONSTANT i32 1
205    %2:_(s64) = G_MERGE_VALUES %0, %1
206    %3:_(s32) = G_EXTRACT %2, 1
207    $vgpr0 = COPY %3
208...
209
210
211# Test with some merges with 3 operands
212
213---
214name: extract_s32_merge_s96_s32_s32_s32_offset0
215
216body: |
217  bb.0:
218    ; CHECK-LABEL: name: extract_s32_merge_s96_s32_s32_s32_offset0
219    ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
220    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[C]](s32)
221    ; CHECK: $vgpr0 = COPY [[COPY]](s32)
222    %0:_(s32) = G_CONSTANT i32 0
223    %1:_(s32) = G_CONSTANT i32 1
224    %2:_(s32) = G_CONSTANT i32 1
225    %3:_(s96) = G_MERGE_VALUES %0, %1, %2
226    %4:_(s32) = G_EXTRACT %3, 0
227    $vgpr0 = COPY %4
228...
229
230---
231name: extract_s32_merge_s96_s32_s32_s32_offset64
232
233body: |
234  bb.0:
235    ; CHECK-LABEL: name: extract_s32_merge_s96_s32_s32_s32_offset64
236    ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
237    ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[C]](s32)
238    ; CHECK: $vgpr0 = COPY [[COPY]](s32)
239    %0:_(s32) = G_CONSTANT i32 0
240    %1:_(s32) = G_CONSTANT i32 1
241    %2:_(s32) = G_CONSTANT i32 1
242    %3:_(s96) = G_MERGE_VALUES %0, %1, %2
243    %4:_(s32) = G_EXTRACT %3, 64
244    $vgpr0 = COPY %4
245...
246
247---
248name: extract_s64_merge_s96_s32_s32_s32_offset0
249
250body: |
251  bb.0:
252    ; CHECK-LABEL: name: extract_s64_merge_s96_s32_s32_s32_offset0
253    ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
254    ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
255    ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
256    ; CHECK: [[MV:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[C]](s32), [[C1]](s32), [[C2]](s32)
257    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s64) = G_EXTRACT [[MV]](s96), 0
258    ; CHECK: $vgpr0_vgpr1 = COPY [[EXTRACT]](s64)
259    %0:_(s32) = G_CONSTANT i32 0
260    %1:_(s32) = G_CONSTANT i32 1
261    %2:_(s32) = G_CONSTANT i32 1
262    %3:_(s96) = G_MERGE_VALUES %0, %1, %2
263    %4:_(s64) = G_EXTRACT %3, 0
264    $vgpr0_vgpr1 = COPY %4
265...
266
267---
268name: extract_s64_merge_s96_s32_s32_s32_offset32
269
270body: |
271  bb.0:
272    ; CHECK-LABEL: name: extract_s64_merge_s96_s32_s32_s32_offset32
273    ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
274    ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
275    ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
276    ; CHECK: [[MV:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[C]](s32), [[C1]](s32), [[C2]](s32)
277    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s64) = G_EXTRACT [[MV]](s96), 32
278    ; CHECK: $vgpr0_vgpr1 = COPY [[EXTRACT]](s64)
279    %0:_(s32) = G_CONSTANT i32 0
280    %1:_(s32) = G_CONSTANT i32 1
281    %2:_(s32) = G_CONSTANT i32 1
282    %3:_(s96) = G_MERGE_VALUES %0, %1, %2
283    %4:_(s64) = G_EXTRACT %3, 32
284    $vgpr0_vgpr1 = COPY %4
285...
286
287# Test build_vector sources
288---
289name: extract_s64_build_vector_v2s64_s64_s64_offset0
290
291body: |
292  bb.0:
293    ; CHECK-LABEL: name: extract_s64_build_vector_v2s64_s64_s64_offset0
294    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
295    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY [[C]](s64)
296    ; CHECK: $vgpr0_vgpr1 = COPY [[COPY]](s64)
297    %0:_(s64) = G_CONSTANT i64 0
298    %1:_(s64) = G_CONSTANT i64 1
299    %2:_(<2 x s64>) = G_BUILD_VECTOR %0, %1
300    %3:_(s64) = G_EXTRACT %2, 0
301    $vgpr0_vgpr1 = COPY %3
302...
303
304---
305name: extract_s64_build_vector_v2s64_s64_s64_offset64
306
307body: |
308  bb.0:
309    ; CHECK-LABEL: name: extract_s64_build_vector_v2s64_s64_s64_offset64
310    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
311    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY [[C]](s64)
312    ; CHECK: $vgpr0_vgpr1 = COPY [[COPY]](s64)
313    %0:_(s64) = G_CONSTANT i64 0
314    %1:_(s64) = G_CONSTANT i64 1
315    %2:_(<2 x s64>) = G_BUILD_VECTOR %0, %1
316    %3:_(s64) = G_EXTRACT %2, 64
317    $vgpr0_vgpr1 = COPY %3
318...
319
320---
321name: extract_s64_build_vector_v2s64_s64_s64_offset32
322
323body: |
324  bb.0:
325    ; CHECK-LABEL: name: extract_s64_build_vector_v2s64_s64_s64_offset32
326    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
327    ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
328    ; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C]](s64), [[C1]](s64)
329    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s64) = G_EXTRACT [[BUILD_VECTOR]](<2 x s64>), 32
330    ; CHECK: $vgpr0_vgpr1 = COPY [[EXTRACT]](s64)
331    %0:_(s64) = G_CONSTANT i64 0
332    %1:_(s64) = G_CONSTANT i64 1
333    %2:_(<2 x s64>) = G_BUILD_VECTOR %0, %1
334    %3:_(s64) = G_EXTRACT %2, 32
335    $vgpr0_vgpr1 = COPY %3
336...
337
338# Test extracting something smaller than the element size
339---
340name: extract_s32_build_vector_v2s64_s64_s64_offset64
341
342body: |
343  bb.0:
344    ; CHECK-LABEL: name: extract_s32_build_vector_v2s64_s64_s64_offset64
345    ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
346    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[C]](s64), 0
347    ; CHECK: $vgpr0 = COPY [[EXTRACT]](s32)
348    %0:_(s64) = G_CONSTANT i64 0
349    %1:_(s64) = G_CONSTANT i64 1
350    %2:_(<2 x s64>) = G_BUILD_VECTOR %0, %1
351    %3:_(s32) = G_EXTRACT %2, 64
352    $vgpr0 = COPY %3
353
354...
355
356# Test concat_vector sources
357---
358name: extract_v2s16_build_vector_v2s64_v2s16_v2s16_offset0
359
360body: |
361  bb.0:
362    liveins: $vgpr0, $vgpr1
363    ; CHECK-LABEL: name: extract_v2s16_build_vector_v2s64_v2s16_v2s16_offset0
364    ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $vgpr0
365    ; CHECK: [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY [[COPY]](<2 x s16>)
366    ; CHECK: $vgpr0 = COPY [[COPY1]](<2 x s16>)
367    %0:_(<2 x s16>) = COPY $vgpr0
368    %1:_(<2 x s16>) = COPY $vgpr1
369    %2:_(<4 x s16>) = G_CONCAT_VECTORS %0, %1
370    %3:_(<2 x s16>) = G_EXTRACT %2, 0
371    $vgpr0 = COPY %3
372...
373
374---
375name: extract_v2s16_build_vector_v2s64_v2s16_v2s16_offset32
376
377body: |
378  bb.0:
379    liveins: $vgpr0, $vgpr1
380    ; CHECK-LABEL: name: extract_v2s16_build_vector_v2s64_v2s16_v2s16_offset32
381    ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $vgpr1
382    ; CHECK: [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY [[COPY]](<2 x s16>)
383    ; CHECK: $vgpr0 = COPY [[COPY1]](<2 x s16>)
384    %0:_(<2 x s16>) = COPY $vgpr0
385    %1:_(<2 x s16>) = COPY $vgpr1
386    %2:_(<4 x s16>) = G_CONCAT_VECTORS %0, %1
387    %3:_(<2 x s16>) = G_EXTRACT %2, 32
388    $vgpr0 = COPY %3
389...
390
391# Test extracting only a single element, not a subvector
392---
393name: extract_s16_build_vector_v2s64_v2s16_v2s16_offset32
394
395body: |
396  bb.0:
397    liveins: $vgpr0, $vgpr1
398    ; CHECK-LABEL: name: extract_s16_build_vector_v2s64_v2s16_v2s16_offset32
399    ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $vgpr1
400    ; CHECK: [[BITCAST:%[0-9]+]]:_(s32) = G_BITCAST [[COPY]](<2 x s16>)
401    ; CHECK: $vgpr0 = COPY [[BITCAST]](s32)
402    %0:_(<2 x s16>) = COPY $vgpr0
403    %1:_(<2 x s16>) = COPY $vgpr1
404    %2:_(<4 x s16>) = G_CONCAT_VECTORS %0, %1
405    %3:_(s16) = G_EXTRACT %2, 32
406    %4:_(s32) = G_ANYEXT %3
407    $vgpr0 = COPY %4
408...
409
410---
411name: extract_s16_build_vector_v2s64_v2s16_v2s16_offset48
412
413body: |
414  bb.0:
415    liveins: $vgpr0, $vgpr1
416    ; CHECK-LABEL: name: extract_s16_build_vector_v2s64_v2s16_v2s16_offset48
417    ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $vgpr1
418    ; CHECK: [[BITCAST:%[0-9]+]]:_(s32) = G_BITCAST [[COPY]](<2 x s16>)
419    ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
420    ; CHECK: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[BITCAST]], [[C]](s32)
421    ; CHECK: $vgpr0 = COPY [[LSHR]](s32)
422    %0:_(<2 x s16>) = COPY $vgpr0
423    %1:_(<2 x s16>) = COPY $vgpr1
424    %2:_(<4 x s16>) = G_CONCAT_VECTORS %0, %1
425    %3:_(s16) = G_EXTRACT %2, 48
426    %4:_(s32) = G_ANYEXT %3
427    $vgpr0 = COPY %4
428...
429
430# Test extracting less than an element
431---
432name: extract_s8_build_vector_v2s64_v2s16_v2s16_offset48
433
434body: |
435  bb.0:
436    liveins: $vgpr0, $vgpr1
437    ; CHECK-LABEL: name: extract_s8_build_vector_v2s64_v2s16_v2s16_offset48
438    ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $vgpr1
439    ; CHECK: [[EXTRACT:%[0-9]+]]:_(s8) = G_EXTRACT [[COPY]](<2 x s16>), 16
440    ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[EXTRACT]](s8)
441    ; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
442    %0:_(<2 x s16>) = COPY $vgpr0
443    %1:_(<2 x s16>) = COPY $vgpr1
444    %2:_(<4 x s16>) = G_CONCAT_VECTORS %0, %1
445    %3:_(s8) = G_EXTRACT %2, 48
446    %4:_(s32) = G_ANYEXT %3
447    $vgpr0 = COPY %4
448...
449