1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -o - -mtriple=aarch64-unknown-unknown -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s | FileCheck %s
4 # Simple unmerge(merge) case with two operands.
5 # The sources of the merge can be used in place of
6 # the destinations of the unmerge.
8 name: test_combine_unmerge_merge
11 ; CHECK-LABEL: name: test_combine_unmerge_merge
12 ; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
13 ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
14 ; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
15 ; CHECK-NEXT: $w1 = COPY [[DEF1]](s32)
16 %0:_(s32) = G_IMPLICIT_DEF
17 %1:_(s32) = G_IMPLICIT_DEF
18 %2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
19 %3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %2(s64)
24 # Simple unmerge(merge) case with three operands.
25 # The sources of the merge can be used in place of
26 # the destinations of the unmerge.
28 name: test_combine_unmerge_merge_3ops
31 ; CHECK-LABEL: name: test_combine_unmerge_merge_3ops
32 ; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
33 ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
34 ; CHECK-NEXT: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
35 ; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
36 ; CHECK-NEXT: $w1 = COPY [[DEF1]](s32)
37 ; CHECK-NEXT: $w2 = COPY [[DEF2]](s32)
38 %0:_(s32) = G_IMPLICIT_DEF
39 %1:_(s32) = G_IMPLICIT_DEF
40 %5:_(s32) = G_IMPLICIT_DEF
41 %2:_(s96) = G_MERGE_VALUES %0(s32), %1(s32), %5(s32)
42 %3:_(s32), %4:_(s32), %6:_(s32) = G_UNMERGE_VALUES %2(s96)
48 # Simple unmerge(buildvector) case with two operands.
49 # The sources of the buildvector can be used in place of
50 # the destinations of the unmerge.
52 name: test_combine_unmerge_build_vector
55 ; CHECK-LABEL: name: test_combine_unmerge_build_vector
56 ; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
57 ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
58 ; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
59 ; CHECK-NEXT: $w1 = COPY [[DEF1]](s32)
60 %0:_(s32) = G_IMPLICIT_DEF
61 %1:_(s32) = G_IMPLICIT_DEF
62 %2:_(<2 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32)
63 %3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %2(<2 x s32>)
68 # Simple unmerge(buildvector) case with three operands.
69 # The sources of the buildvector can be used in place of
70 # the destinations of the unmerge.
72 name: test_combine_unmerge_buildvector_3ops
75 ; CHECK-LABEL: name: test_combine_unmerge_buildvector_3ops
76 ; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
77 ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
78 ; CHECK-NEXT: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
79 ; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
80 ; CHECK-NEXT: $w1 = COPY [[DEF1]](s32)
81 ; CHECK-NEXT: $w2 = COPY [[DEF2]](s32)
82 %0:_(s32) = G_IMPLICIT_DEF
83 %1:_(s32) = G_IMPLICIT_DEF
84 %5:_(s32) = G_IMPLICIT_DEF
85 %2:_(<3 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %5(s32)
86 %3:_(s32), %4:_(s32), %6:_(s32) = G_UNMERGE_VALUES %2(<3 x s32>)
92 # Simple unmerge(concatvectors) case.
93 # The sources of the concatvectors can be used in place of
94 # the destinations of the unmerge.
96 name: test_combine_unmerge_concat_vectors
99 ; CHECK-LABEL: name: test_combine_unmerge_concat_vectors
100 ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $w0
101 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY $w1
102 ; CHECK-NEXT: $w0 = COPY [[COPY]](<2 x s16>)
103 ; CHECK-NEXT: $w1 = COPY [[COPY1]](<2 x s16>)
104 %0:_(<2 x s16>) = COPY $w0
105 %1:_(<2 x s16>) = COPY $w1
106 %2:_(<4 x s16>) = G_CONCAT_VECTORS %0(<2 x s16>), %1(<2 x s16>)
107 %3:_(<2 x s16>), %4:_(<2 x s16>) = G_UNMERGE_VALUES %2(<4 x s16>)
108 $w0 = COPY %3(<2 x s16>)
109 $w1 = COPY %4(<2 x s16>)
112 # Unmerge(merge) case with two operands and a bitcast in the middle.
113 # The sources of the merge can be used in place of
114 # the destinations of the unmerge.
116 name: test_combine_unmerge_bitcast_merge
119 ; CHECK-LABEL: name: test_combine_unmerge_bitcast_merge
120 ; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
121 ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
122 ; CHECK-NEXT: $w0 = COPY [[DEF]](s32)
123 ; CHECK-NEXT: $w1 = COPY [[DEF1]](s32)
124 %0:_(s32) = G_IMPLICIT_DEF
125 %1:_(s32) = G_IMPLICIT_DEF
126 %2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
127 %5:_(<2 x s32>) = G_BITCAST %2(s64)
128 %3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %5(<2 x s32>)
133 # Unmerge(merge) with incompatible types: unmerge destTy != merge inputTy.
134 # The sources of the merge cannot be used in place of
135 # the destinations of the unmerge, since the types don't match.
137 name: test_combine_unmerge_merge_incompatible_types
140 ; CHECK-LABEL: name: test_combine_unmerge_merge_incompatible_types
141 ; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
142 ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
143 ; CHECK-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[DEF]](s32), [[DEF1]](s32)
144 ; CHECK-NEXT: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[MV]](s64)
145 ; CHECK-NEXT: $h0 = COPY [[UV]](s16)
146 ; CHECK-NEXT: $h1 = COPY [[UV1]](s16)
147 ; CHECK-NEXT: $h2 = COPY [[UV2]](s16)
148 ; CHECK-NEXT: $h3 = COPY [[UV3]](s16)
149 %0:_(s32) = G_IMPLICIT_DEF
150 %1:_(s32) = G_IMPLICIT_DEF
151 %2:_(s64) = G_MERGE_VALUES %0(s32), %1(s32)
152 %3:_(s16), %4:_(s16), %5:_(s16), %6:_(s16) = G_UNMERGE_VALUES %2(s64)
159 # Unmerge(concatvectors) with incompatible types: unmerge destTy != merge inputTy
160 # but destTy.size() == inputTy.size().
161 # The sources of the concatvectors can be used in place of
162 # the destinations of the unmerge with a bitcast since the sizes
165 name: test_combine_unmerge_merge_incompatible_types_but_same_size
168 ; CHECK-LABEL: name: test_combine_unmerge_merge_incompatible_types_but_same_size
169 ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $w0
170 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY $w1
171 ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s32) = G_BITCAST [[COPY]](<2 x s16>)
172 ; CHECK-NEXT: [[BITCAST1:%[0-9]+]]:_(s32) = G_BITCAST [[COPY1]](<2 x s16>)
173 ; CHECK-NEXT: $w0 = COPY [[BITCAST]](s32)
174 ; CHECK-NEXT: $w1 = COPY [[BITCAST1]](s32)
175 %0:_(<2 x s16>) = COPY $w0
176 %1:_(<2 x s16>) = COPY $w1
177 %2:_(<4 x s16>) = G_CONCAT_VECTORS %0(<2 x s16>), %1(<2 x s16>)
178 %5:_(s64) = G_BITCAST %2(<4 x s16>)
179 %3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %5(s64)
184 # Unmerge a constant into a bunch of smaller constant.
185 # Constant is 0x0102030405060708090a0b0c0d0e0f10 and we break it down into
192 name: test_combine_unmerge_cst
195 ; CHECK-LABEL: name: test_combine_unmerge_cst
196 ; CHECK: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 16
197 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 15
198 ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s8) = G_CONSTANT i8 14
199 ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s8) = G_CONSTANT i8 13
200 ; CHECK-NEXT: [[C4:%[0-9]+]]:_(s8) = G_CONSTANT i8 12
201 ; CHECK-NEXT: [[C5:%[0-9]+]]:_(s8) = G_CONSTANT i8 11
202 ; CHECK-NEXT: [[C6:%[0-9]+]]:_(s8) = G_CONSTANT i8 10
203 ; CHECK-NEXT: [[C7:%[0-9]+]]:_(s8) = G_CONSTANT i8 9
204 ; CHECK-NEXT: [[C8:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
205 ; CHECK-NEXT: [[C9:%[0-9]+]]:_(s8) = G_CONSTANT i8 7
206 ; CHECK-NEXT: [[C10:%[0-9]+]]:_(s8) = G_CONSTANT i8 6
207 ; CHECK-NEXT: [[C11:%[0-9]+]]:_(s8) = G_CONSTANT i8 5
208 ; CHECK-NEXT: [[C12:%[0-9]+]]:_(s8) = G_CONSTANT i8 4
209 ; CHECK-NEXT: [[C13:%[0-9]+]]:_(s8) = G_CONSTANT i8 3
210 ; CHECK-NEXT: [[C14:%[0-9]+]]:_(s8) = G_CONSTANT i8 2
211 ; CHECK-NEXT: [[C15:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
212 ; CHECK-NEXT: $b0 = COPY [[C]](s8)
213 ; CHECK-NEXT: $b1 = COPY [[C1]](s8)
214 ; CHECK-NEXT: $b2 = COPY [[C2]](s8)
215 ; CHECK-NEXT: $b3 = COPY [[C3]](s8)
216 ; CHECK-NEXT: $b4 = COPY [[C4]](s8)
217 ; CHECK-NEXT: $b5 = COPY [[C5]](s8)
218 ; CHECK-NEXT: $b6 = COPY [[C6]](s8)
219 ; CHECK-NEXT: $b7 = COPY [[C7]](s8)
220 ; CHECK-NEXT: $b8 = COPY [[C8]](s8)
221 ; CHECK-NEXT: $b9 = COPY [[C9]](s8)
222 ; CHECK-NEXT: $b10 = COPY [[C10]](s8)
223 ; CHECK-NEXT: $b11 = COPY [[C11]](s8)
224 ; CHECK-NEXT: $b12 = COPY [[C12]](s8)
225 ; CHECK-NEXT: $b13 = COPY [[C13]](s8)
226 ; CHECK-NEXT: $b14 = COPY [[C14]](s8)
227 ; CHECK-NEXT: $b15 = COPY [[C15]](s8)
228 %0:_(s128) = G_CONSTANT i128 1339673755198158349044581307228491536
229 %1:_(s8),%2:_(s8),%3:_(s8),%4:_(s8),%5:_(s8),%6:_(s8),%7:_(s8),%8:_(s8),%9:_(s8),%10:_(s8),%11:_(s8),%12:_(s8),%13:_(s8),%14:_(s8),%15:_(s8),%16:_(s8) = G_UNMERGE_VALUES %0(s128)
248 # Unmerge a constant on a non-power of 2 type into a bunch of smaller constant.
249 # Constant is a 3 | 2 | 1 in chunks of 13-bit.
251 name: test_combine_unmerge_cst_36bit
254 ; CHECK-LABEL: name: test_combine_unmerge_cst_36bit
255 ; CHECK: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
256 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
257 ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s16) = G_CONSTANT i16 3
258 ; CHECK-NEXT: $h0 = COPY [[C]](s16)
259 ; CHECK-NEXT: $h1 = COPY [[C1]](s16)
260 ; CHECK-NEXT: $h2 = COPY [[C2]](s16)
261 %0:_(s39) = G_CONSTANT i39 201342977
262 %1:_(s13),%2:_(s13),%3:_(s13) = G_UNMERGE_VALUES %0(s39)
263 %4:_(s16) = G_ZEXT %1(s13)
264 %5:_(s16) = G_ZEXT %2(s13)
265 %6:_(s16) = G_ZEXT %3(s13)
271 # Unmerge floating point constant.
273 name: test_combine_unmerge_fpcst
276 ; CHECK-LABEL: name: test_combine_unmerge_fpcst
277 ; CHECK: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
278 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
279 ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s16) = G_CONSTANT i16 3
280 ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s16) = G_CONSTANT i16 4
281 ; CHECK-NEXT: $h0 = COPY [[C]](s16)
282 ; CHECK-NEXT: $h1 = COPY [[C1]](s16)
283 ; CHECK-NEXT: $h2 = COPY [[C2]](s16)
284 ; CHECK-NEXT: $h3 = COPY [[C3]](s16)
285 %0:_(s64) = G_FCONSTANT double 0x0004000300020001
286 %1:_(s16),%2:_(s16),%3:_(s16),%4:_(s16) = G_UNMERGE_VALUES %0(s64)
293 # Transform unmerge into trunc when only the first definition is live.
295 name: test_combine_unmerge_dead_to_trunc
298 ; CHECK-LABEL: name: test_combine_unmerge_dead_to_trunc
299 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
300 ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s64)
301 ; CHECK-NEXT: $h0 = COPY [[TRUNC]](s16)
303 %1:_(s16),%2:_(s16),%3:_(s16),%4:_(s16) = G_UNMERGE_VALUES %0(s64)
307 # Don't transform unmerge into trunc when middle lanes are live.
309 name: test_dont_combine_unmerge_dead_to_trunc
312 ; CHECK-LABEL: name: test_dont_combine_unmerge_dead_to_trunc
313 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
314 ; CHECK-NEXT: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[COPY]](s64)
315 ; CHECK-NEXT: $h0 = COPY [[UV2]](s16)
317 %1:_(s16),%2:_(s16),%3:_(s16),%4:_(s16) = G_UNMERGE_VALUES %0(s64)
321 # Transform unmerge into trunc when only the first definition is live, even
322 # if the input and output types are vectors.
324 name: test_combine_unmerge_dead_to_trunc_vec_in_n_out
327 ; CHECK-LABEL: name: test_combine_unmerge_dead_to_trunc_vec_in_n_out
328 ; CHECK: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $x0
329 ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s64) = G_BITCAST [[COPY]](<4 x s16>)
330 ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[BITCAST]](s64)
331 ; CHECK-NEXT: [[BITCAST1:%[0-9]+]]:_(<2 x s16>) = G_BITCAST [[TRUNC]](s32)
332 ; CHECK-NEXT: $w0 = COPY [[BITCAST1]](<2 x s16>)
333 %0:_(<4 x s16>) = COPY $x0
334 %1:_(<2 x s16>),%2:_(<2 x s16>) = G_UNMERGE_VALUES %0(<4 x s16>)
335 $w0 = COPY %1(<2 x s16>)
338 # Transform unmerge into trunc when only the first definition is live, even
339 # if the input type is vector.
341 name: test_combine_unmerge_dead_to_trunc_vec_in
344 ; CHECK-LABEL: name: test_combine_unmerge_dead_to_trunc_vec_in
345 ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $x0
346 ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s64) = G_BITCAST [[COPY]](<2 x s32>)
347 ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[BITCAST]](s64)
348 ; CHECK-NEXT: $h0 = COPY [[TRUNC]](s16)
349 %0:_(<2 x s32>) = COPY $x0
350 %1:_(s16),%2:_(s16),%3:_(s16),%4:_(s16) = G_UNMERGE_VALUES %0(<2 x s32>)
354 # Transform unmerge(zext) into zext.
355 # In that test, the source of the zext is same size as the first definition
356 # of the unmerge. Therefore a we can just reuse the input of the zext for
359 name: test_combine_unmerge_zext_to_zext_same_size
362 ; CHECK-LABEL: name: test_combine_unmerge_zext_to_zext_same_size
363 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
364 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
365 ; CHECK-NEXT: $w0 = COPY [[COPY]](s32)
366 ; CHECK-NEXT: $w1 = COPY [[C]](s32)
368 %3:_(s64) = G_ZEXT %0(s32)
369 %1:_(s32),%2:_(s32) = G_UNMERGE_VALUES %3(s64)
374 # Transform unmerge(zext) into zext.
375 # In that test, the source of the zext is smaller than the first definition
376 # of the unmerge. Therefore a G_ZEXT is required.
378 name: test_combine_unmerge_zext_to_zext
381 ; CHECK-LABEL: name: test_combine_unmerge_zext_to_zext
382 ; CHECK: [[COPY:%[0-9]+]]:_(s8) = COPY $b0
383 ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[COPY]](s8)
384 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
385 ; CHECK-NEXT: $h0 = COPY [[ZEXT]](s16)
386 ; CHECK-NEXT: $h1 = COPY [[C]](s16)
387 ; CHECK-NEXT: $h2 = COPY [[C]](s16)
388 ; CHECK-NEXT: $h3 = COPY [[C]](s16)
390 %3:_(s64) = G_ZEXT %0(s8)
391 %1:_(s16),%2:_(s16),%4:_(s16),%5:_(s16) = G_UNMERGE_VALUES %3(s64)
398 # Check that we don't apply the unmerge(zext) to zext transformation
399 # when the first destination of the unmerge is smaller than the source
402 name: test_dont_combine_unmerge_zext_to_zext_src_bigger
405 ; CHECK-LABEL: name: test_dont_combine_unmerge_zext_to_zext_src_bigger
406 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
407 ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY]](s32)
408 ; CHECK-NEXT: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[ZEXT]](s64)
409 ; CHECK-NEXT: $h0 = COPY [[UV]](s16)
410 ; CHECK-NEXT: $h1 = COPY [[UV1]](s16)
411 ; CHECK-NEXT: $h2 = COPY [[UV2]](s16)
412 ; CHECK-NEXT: $h3 = COPY [[UV3]](s16)
414 %3:_(s64) = G_ZEXT %0(s32)
415 %1:_(s16),%2:_(s16),%4:_(s16),%5:_(s16) = G_UNMERGE_VALUES %3(s64)
422 # Check that we don't apply the unmerge(zext) to zext transformation
423 # when the input zext deals with a vector type.
425 name: test_dont_combine_unmerge_zext_to_zext_src_vector
428 ; CHECK-LABEL: name: test_dont_combine_unmerge_zext_to_zext_src_vector
429 ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s16>) = COPY $w0
430 ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(<2 x s32>) = G_ZEXT [[COPY]](<2 x s16>)
431 ; CHECK-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ZEXT]](<2 x s32>)
432 ; CHECK-NEXT: $w0 = COPY [[UV]](s32)
433 ; CHECK-NEXT: $w1 = COPY [[UV1]](s32)
434 %0:_(<2 x s16>) = COPY $w0
435 %3:_(<2 x s32>) = G_ZEXT %0(<2 x s16>)
436 %1:_(s32),%2:_(s32) = G_UNMERGE_VALUES %3(<2 x s32>)