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
5 name: extract_s32_merge_s64_s32_s32_offset0
9 ; CHECK-LABEL: name: extract_s32_merge_s64_s32_s32_offset0
10 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
11 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY [[C]](s32)
12 ; CHECK-NEXT: $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
21 name: extract_s32_merge_s64_s32_s32_offset32
25 ; CHECK-LABEL: name: extract_s32_merge_s64_s32_s32_offset32
26 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
27 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY [[C]](s32)
28 ; CHECK-NEXT: $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
37 name: extract_s64_merge_s128_s64_s64_offset0
41 ; CHECK-LABEL: name: extract_s64_merge_s128_s64_s64_offset0
42 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
43 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY [[C]](s64)
44 ; CHECK-NEXT: $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
53 name: extract_s64_merge_s128_s64_s64_offset64
57 ; CHECK-LABEL: name: extract_s64_merge_s128_s64_s64_offset64
58 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
59 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY [[C]](s64)
60 ; CHECK-NEXT: $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
69 name: extract_s32_merge_s128_s64_s64_offset0
73 ; CHECK-LABEL: name: extract_s32_merge_s128_s64_s64_offset0
74 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
75 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[C]](s64), 0
76 ; CHECK-NEXT: $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
85 name: extract_s32_merge_s128_s64_s64_offset32
89 ; CHECK-LABEL: name: extract_s32_merge_s128_s64_s64_offset32
90 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
91 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[C]](s64), 32
92 ; CHECK-NEXT: $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
101 name: extract_s32_merge_s128_s64_s64_offset64
105 ; CHECK-LABEL: name: extract_s32_merge_s128_s64_s64_offset64
106 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
107 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[C]](s64), 0
108 ; CHECK-NEXT: $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
117 name: extract_s32_merge_s128_s64_s64_offset96
121 ; CHECK-LABEL: name: extract_s32_merge_s128_s64_s64_offset96
122 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
123 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[C]](s64), 32
124 ; CHECK-NEXT: $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
132 # Destination size fits, but is skewed from the start of the register.
134 name: extract_s16_merge_s128_s64_s64_offset18
138 ; CHECK-LABEL: name: extract_s16_merge_s128_s64_s64_offset18
139 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
140 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s16) = G_EXTRACT [[C]](s64), 18
141 ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[EXTRACT]](s16)
142 ; CHECK-NEXT: $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
151 # Destination size fits, but is skewed from the start of the register.
153 name: extract_s16_merge_s128_s64_s64_offset82
157 ; CHECK-LABEL: name: extract_s16_merge_s128_s64_s64_offset82
158 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
159 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s16) = G_EXTRACT [[C]](s64), 18
160 ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[EXTRACT]](s16)
161 ; CHECK-NEXT: $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
171 # Can't handle this since it spans two registers
173 name: extract_s64_merge_s128_s64_s64_offset32
177 ; CHECK-LABEL: name: extract_s64_merge_s128_s64_s64_offset32
178 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
179 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
180 ; CHECK-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[C]](s64), [[C1]](s64)
181 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s64) = G_EXTRACT [[MV]](s128), 32
182 ; CHECK-NEXT: $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
191 # Only the last bit spans to another register
193 name: extract_s16_merge_s32_s32_offset1
197 ; CHECK-LABEL: name: extract_s16_merge_s32_s32_offset1
198 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
199 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
200 ; CHECK-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[C]](s32), [[C1]](s32)
201 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[MV]](s64), 1
202 ; CHECK-NEXT: $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
211 # Test with some merges with 3 operands
214 name: extract_s32_merge_s96_s32_s32_s32_offset0
218 ; CHECK-LABEL: name: extract_s32_merge_s96_s32_s32_s32_offset0
219 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
220 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY [[C]](s32)
221 ; CHECK-NEXT: $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
231 name: extract_s32_merge_s96_s32_s32_s32_offset64
235 ; CHECK-LABEL: name: extract_s32_merge_s96_s32_s32_s32_offset64
236 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
237 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY [[C]](s32)
238 ; CHECK-NEXT: $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
248 name: extract_s64_merge_s96_s32_s32_s32_offset0
252 ; CHECK-LABEL: name: extract_s64_merge_s96_s32_s32_s32_offset0
253 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
254 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
255 ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
256 ; CHECK-NEXT: [[MV:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[C]](s32), [[C1]](s32), [[C2]](s32)
257 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s64) = G_EXTRACT [[MV]](s96), 0
258 ; CHECK-NEXT: $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
268 name: extract_s64_merge_s96_s32_s32_s32_offset32
272 ; CHECK-LABEL: name: extract_s64_merge_s96_s32_s32_s32_offset32
273 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
274 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
275 ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
276 ; CHECK-NEXT: [[MV:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[C]](s32), [[C1]](s32), [[C2]](s32)
277 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s64) = G_EXTRACT [[MV]](s96), 32
278 ; CHECK-NEXT: $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
287 # Test build_vector sources
289 name: extract_s64_build_vector_v2s64_s64_s64_offset0
293 ; CHECK-LABEL: name: extract_s64_build_vector_v2s64_s64_s64_offset0
294 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
295 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY [[C]](s64)
296 ; CHECK-NEXT: $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
305 name: extract_s64_build_vector_v2s64_s64_s64_offset64
309 ; CHECK-LABEL: name: extract_s64_build_vector_v2s64_s64_s64_offset64
310 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
311 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY [[C]](s64)
312 ; CHECK-NEXT: $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
321 name: extract_s64_build_vector_v2s64_s64_s64_offset32
325 ; CHECK-LABEL: name: extract_s64_build_vector_v2s64_s64_s64_offset32
326 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
327 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
328 ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C]](s64), [[C1]](s64)
329 ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s128) = G_BITCAST [[BUILD_VECTOR]](<2 x s64>)
330 ; CHECK-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[BITCAST]](s128)
331 ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 32
332 ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s64) = G_LSHR [[UV]], [[C2]](s32)
333 ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[UV1]], [[C2]](s32)
334 ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[LSHR]], [[SHL]]
335 ; CHECK-NEXT: $vgpr0_vgpr1 = COPY [[OR]](s64)
336 %0:_(s64) = G_CONSTANT i64 0
337 %1:_(s64) = G_CONSTANT i64 1
338 %2:_(<2 x s64>) = G_BUILD_VECTOR %0, %1
339 %3:_(s64) = G_EXTRACT %2, 32
340 $vgpr0_vgpr1 = COPY %3
343 # Test extracting something smaller than the element size
345 name: extract_s32_build_vector_v2s64_s64_s64_offset64
349 ; CHECK-LABEL: name: extract_s32_build_vector_v2s64_s64_s64_offset64
350 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
351 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s32) = G_EXTRACT [[C]](s64), 0
352 ; CHECK-NEXT: $vgpr0 = COPY [[EXTRACT]](s32)
353 %0:_(s64) = G_CONSTANT i64 0
354 %1:_(s64) = G_CONSTANT i64 1
355 %2:_(<2 x s64>) = G_BUILD_VECTOR %0, %1
356 %3:_(s32) = G_EXTRACT %2, 64
361 # Test concat_vector sources
363 name: extract_v2s16_build_vector_v2s64_v2s16_v2s16_offset0
367 liveins: $vgpr0, $vgpr1
368 ; CHECK-LABEL: name: extract_v2s16_build_vector_v2s64_v2s16_v2s16_offset0
369 ; CHECK: liveins: $vgpr0, $vgpr1
371 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $vgpr0
372 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY [[COPY]](<2 x s16>)
373 ; CHECK-NEXT: $vgpr0 = COPY [[COPY1]](<2 x s16>)
374 %0:_(<2 x s16>) = COPY $vgpr0
375 %1:_(<2 x s16>) = COPY $vgpr1
376 %2:_(<4 x s16>) = G_CONCAT_VECTORS %0, %1
377 %3:_(<2 x s16>) = G_EXTRACT %2, 0
382 name: extract_v2s16_build_vector_v2s64_v2s16_v2s16_offset32
386 liveins: $vgpr0, $vgpr1
387 ; CHECK-LABEL: name: extract_v2s16_build_vector_v2s64_v2s16_v2s16_offset32
388 ; CHECK: liveins: $vgpr0, $vgpr1
390 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $vgpr1
391 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY [[COPY]](<2 x s16>)
392 ; CHECK-NEXT: $vgpr0 = COPY [[COPY1]](<2 x s16>)
393 %0:_(<2 x s16>) = COPY $vgpr0
394 %1:_(<2 x s16>) = COPY $vgpr1
395 %2:_(<4 x s16>) = G_CONCAT_VECTORS %0, %1
396 %3:_(<2 x s16>) = G_EXTRACT %2, 32
400 # Test extracting only a single element, not a subvector
402 name: extract_s16_build_vector_v2s64_v2s16_v2s16_offset32
406 liveins: $vgpr0, $vgpr1
407 ; CHECK-LABEL: name: extract_s16_build_vector_v2s64_v2s16_v2s16_offset32
408 ; CHECK: liveins: $vgpr0, $vgpr1
410 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $vgpr1
411 ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s32) = G_BITCAST [[COPY]](<2 x s16>)
412 ; CHECK-NEXT: $vgpr0 = COPY [[BITCAST]](s32)
413 %0:_(<2 x s16>) = COPY $vgpr0
414 %1:_(<2 x s16>) = COPY $vgpr1
415 %2:_(<4 x s16>) = G_CONCAT_VECTORS %0, %1
416 %3:_(s16) = G_EXTRACT %2, 32
417 %4:_(s32) = G_ANYEXT %3
422 name: extract_s16_build_vector_v2s64_v2s16_v2s16_offset48
426 liveins: $vgpr0, $vgpr1
427 ; CHECK-LABEL: name: extract_s16_build_vector_v2s64_v2s16_v2s16_offset48
428 ; CHECK: liveins: $vgpr0, $vgpr1
430 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $vgpr1
431 ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s32) = G_BITCAST [[COPY]](<2 x s16>)
432 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
433 ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[BITCAST]], [[C]](s32)
434 ; CHECK-NEXT: $vgpr0 = COPY [[LSHR]](s32)
435 %0:_(<2 x s16>) = COPY $vgpr0
436 %1:_(<2 x s16>) = COPY $vgpr1
437 %2:_(<4 x s16>) = G_CONCAT_VECTORS %0, %1
438 %3:_(s16) = G_EXTRACT %2, 48
439 %4:_(s32) = G_ANYEXT %3
443 # Test extracting less than an element
445 name: extract_s8_build_vector_v2s64_v2s16_v2s16_offset48
449 liveins: $vgpr0, $vgpr1
450 ; CHECK-LABEL: name: extract_s8_build_vector_v2s64_v2s16_v2s16_offset48
451 ; CHECK: liveins: $vgpr0, $vgpr1
453 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $vgpr1
454 ; CHECK-NEXT: [[EXTRACT:%[0-9]+]]:_(s8) = G_EXTRACT [[COPY]](<2 x s16>), 16
455 ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[EXTRACT]](s8)
456 ; CHECK-NEXT: $vgpr0 = COPY [[ANYEXT]](s32)
457 %0:_(<2 x s16>) = COPY $vgpr0
458 %1:_(<2 x s16>) = COPY $vgpr1
459 %2:_(<4 x s16>) = G_CONCAT_VECTORS %0, %1
460 %3:_(s8) = G_EXTRACT %2, 48
461 %4:_(s32) = G_ANYEXT %3