1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -mtriple=aarch64 -run-pass=aarch64-postlegalizer-lowering -verify-machineinstrs %s -o - | FileCheck %s
8 tracksRegLiveness: true
13 ; CHECK-LABEL: name: splat_4xi32
16 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
17 ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[COPY]](s32)
18 ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x s32>)
19 ; CHECK-NEXT: RET_ReallyLR implicit $q0
21 %2:_(<4 x s32>) = G_IMPLICIT_DEF
22 %3:_(s32) = G_CONSTANT i32 0
23 %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s32)
24 %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, 0, 0, 0)
25 $q0 = COPY %4(<4 x s32>)
26 RET_ReallyLR implicit $q0
33 tracksRegLiveness: true
38 ; CHECK-LABEL: name: splat_2xi64
41 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
42 ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64)
43 ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>)
44 ; CHECK-NEXT: RET_ReallyLR implicit $q0
46 %2:_(<2 x s64>) = G_IMPLICIT_DEF
47 %3:_(s32) = G_CONSTANT i32 0
48 %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s32)
49 %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 0)
50 $q0 = COPY %4(<2 x s64>)
51 RET_ReallyLR implicit $q0
58 tracksRegLiveness: true
63 ; CHECK-LABEL: name: splat_2xi32
66 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
67 ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s32>) = G_DUP [[COPY]](s32)
68 ; CHECK-NEXT: $d0 = COPY [[DUP]](<2 x s32>)
69 ; CHECK-NEXT: RET_ReallyLR implicit $d0
71 %2:_(<2 x s32>) = G_IMPLICIT_DEF
72 %3:_(s32) = G_CONSTANT i32 0
73 %1:_(<2 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s32)
74 %4:_(<2 x s32>) = G_SHUFFLE_VECTOR %1(<2 x s32>), %2, shufflemask(0, 0)
75 $d0 = COPY %4(<2 x s32>)
76 RET_ReallyLR implicit $d0
83 tracksRegLiveness: true
88 ; CHECK-LABEL: name: splat_4xf32
91 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0
92 ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[COPY]](s32)
93 ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x s32>)
94 ; CHECK-NEXT: RET_ReallyLR implicit $q0
96 %2:_(<4 x s32>) = G_IMPLICIT_DEF
97 %3:_(s32) = G_CONSTANT i32 0
98 %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s32)
99 %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, 0, 0, 0)
100 $q0 = COPY %4(<4 x s32>)
101 RET_ReallyLR implicit $q0
108 tracksRegLiveness: true
113 ; CHECK-LABEL: name: splat_2xf64
114 ; CHECK: liveins: $d0
116 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $d0
117 ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64)
118 ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>)
119 ; CHECK-NEXT: RET_ReallyLR implicit $q0
121 %2:_(<2 x s64>) = G_IMPLICIT_DEF
122 %3:_(s32) = G_CONSTANT i32 0
123 %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s32)
124 %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 0)
125 $q0 = COPY %4(<2 x s64>)
126 RET_ReallyLR implicit $q0
133 tracksRegLiveness: true
138 ; CHECK-LABEL: name: splat_2xf32
139 ; CHECK: liveins: $s0
141 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0
142 ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s32>) = G_DUP [[COPY]](s32)
143 ; CHECK-NEXT: $d0 = COPY [[DUP]](<2 x s32>)
144 ; CHECK-NEXT: RET_ReallyLR implicit $d0
146 %2:_(<2 x s32>) = G_IMPLICIT_DEF
147 %3:_(s32) = G_CONSTANT i32 0
148 %1:_(<2 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s32)
149 %4:_(<2 x s32>) = G_SHUFFLE_VECTOR %1(<2 x s32>), %2, shufflemask(0, 0)
150 $d0 = COPY %4(<2 x s32>)
151 RET_ReallyLR implicit $d0
155 name: splat_2xf64_copies
158 tracksRegLiveness: true
163 ; This test is exactly the same as splat_2xf64, except it adds two copies.
164 ; These copies shouldn't get in the way of matching the dup pattern.
165 ; CHECK-LABEL: name: splat_2xf64_copies
166 ; CHECK: liveins: $d0
168 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $d0
169 ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64)
170 ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>)
171 ; CHECK-NEXT: RET_ReallyLR implicit $q0
173 %2:_(<2 x s64>) = G_IMPLICIT_DEF
174 %6:_(<2 x s64>) = COPY %2
175 %3:_(s32) = G_CONSTANT i32 0
176 %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %6, %0(s64), %3(s32)
177 %7:_(<2 x s64>) = COPY %1
178 %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %7(<2 x s64>), %2, shufflemask(0, 0)
179 $q0 = COPY %4(<2 x s64>)
180 RET_ReallyLR implicit $q0
187 tracksRegLiveness: true
191 ; Make sure that we don't do the optimization when it's not all zeroes.
192 ; CHECK-LABEL: name: not_all_zeros
193 ; CHECK: liveins: $x0
195 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
196 ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF
197 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
198 ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<2 x s64>) = G_INSERT_VECTOR_ELT [[DEF]], [[COPY]](s64), [[C]](s32)
199 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY [[IVEC]](<2 x s64>)
200 ; CHECK-NEXT: $q0 = COPY [[COPY1]](<2 x s64>)
201 ; CHECK-NEXT: RET_ReallyLR implicit $q0
203 %2:_(<2 x s64>) = G_IMPLICIT_DEF
204 %3:_(s32) = G_CONSTANT i32 0
205 %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s32)
206 %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 1)
207 $q0 = COPY %4(<2 x s64>)
208 RET_ReallyLR implicit $q0
215 tracksRegLiveness: true
219 ; If all the elements are undefined, we consider it a splat. In this case,
220 ; we can choose 0 as our index.
222 ; We should get a G_DUP here.
224 ; CHECK-LABEL: name: all_undef
225 ; CHECK: liveins: $x0
227 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
228 ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64)
229 ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>)
230 ; CHECK-NEXT: RET_ReallyLR implicit $q0
232 %2:_(<2 x s64>) = G_IMPLICIT_DEF
233 %3:_(s32) = G_CONSTANT i32 0
234 %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s32)
235 %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(-1, -1)
236 $q0 = COPY %4(<2 x s64>)
237 RET_ReallyLR implicit $q0
244 tracksRegLiveness: true
248 ; Make sure we can skip past undef values.
250 ; We should get a G_DUP here.
252 ; CHECK-LABEL: name: one_undef
253 ; CHECK: liveins: $s0
255 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0
256 ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[COPY]](s32)
257 ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x s32>)
258 ; CHECK-NEXT: RET_ReallyLR implicit $q0
260 %2:_(<4 x s32>) = G_IMPLICIT_DEF
261 %3:_(s32) = G_CONSTANT i32 0
262 %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s32)
263 %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, -1, 0, 0)
264 $q0 = COPY %4(<4 x s32>)
265 RET_ReallyLR implicit $q0
269 name: not_all_zeros_with_undefs
272 tracksRegLiveness: true
276 ; Check a non-splat mask with an undef value. We shouldn't get a G_DUP here.
278 ; CHECK-LABEL: name: not_all_zeros_with_undefs
279 ; CHECK: liveins: $s0
281 ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0
282 ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF
283 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
284 ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[DEF]], [[COPY]](s32), [[C]](s32)
285 ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[IVEC]](<4 x s32>), [[DEF]], shufflemask(undef, 0, 0, 3)
286 ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x s32>)
287 ; CHECK-NEXT: RET_ReallyLR implicit $q0
289 %2:_(<4 x s32>) = G_IMPLICIT_DEF
290 %3:_(s32) = G_CONSTANT i32 0
291 %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s32)
292 %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(-1, 0, 0, 3)
293 $q0 = COPY %4(<4 x s32>)
294 RET_ReallyLR implicit $q0
301 tracksRegLiveness: true
305 ; CHECK-LABEL: name: splat_4xi16
306 ; CHECK: liveins: $h0
308 ; CHECK-NEXT: %copy:_(s16) = COPY $h0
309 ; CHECK-NEXT: %splat:_(<4 x s16>) = G_DUP %copy(s16)
310 ; CHECK-NEXT: $d0 = COPY %splat(<4 x s16>)
311 ; CHECK-NEXT: RET_ReallyLR implicit $d0
312 %copy:_(s16) = COPY $h0
313 %undef:_(<4 x s16>) = G_IMPLICIT_DEF
314 %cst:_(s32) = G_CONSTANT i32 0
315 %ins:_(<4 x s16>) = G_INSERT_VECTOR_ELT %undef, %copy(s16), %cst(s32)
316 %splat:_(<4 x s16>) = G_SHUFFLE_VECTOR %ins(<4 x s16>), %undef, shufflemask(0, 0, 0, 0)
317 $d0 = COPY %splat(<4 x s16>)
318 RET_ReallyLR implicit $d0
325 tracksRegLiveness: true
329 ; CHECK-LABEL: name: splat_8xi8
330 ; CHECK: liveins: $w0
332 ; CHECK-NEXT: %copy:_(s32) = COPY $w0
333 ; CHECK-NEXT: %splat:_(<8 x s8>) = G_DUP %copy(s32)
334 ; CHECK-NEXT: $d0 = COPY %splat(<8 x s8>)
335 ; CHECK-NEXT: RET_ReallyLR implicit $d0
336 %copy:_(s32) = COPY $w0
337 %undef:_(<8 x s8>) = G_IMPLICIT_DEF
338 %cst:_(s32) = G_CONSTANT i32 0
339 %ins:_(<8 x s8>) = G_INSERT_VECTOR_ELT %undef, %copy(s32), %cst(s32)
340 %splat:_(<8 x s8>) = G_SHUFFLE_VECTOR %ins(<8 x s8>), %undef, shufflemask(0, 0, 0, 0, 0, 0, 0, 0)
341 $d0 = COPY %splat(<8 x s8>)
342 RET_ReallyLR implicit $d0
349 tracksRegLiveness: true
352 liveins: $w0, $w1, $w2, $w3
353 ; The G_SHUFFLE_VECTOR is fed by a G_BUILD_VECTOR, and the 0th input
354 ; operand is not a constant. We should get a G_DUP.
356 ; CHECK-LABEL: name: build_vector
357 ; CHECK: liveins: $w0, $w1, $w2, $w3
359 ; CHECK-NEXT: %lane:_(s32) = COPY $w0
360 ; CHECK-NEXT: %shuf:_(<4 x s32>) = G_DUP %lane(s32)
361 ; CHECK-NEXT: $q0 = COPY %shuf(<4 x s32>)
362 ; CHECK-NEXT: RET_ReallyLR implicit $q0
363 %lane:_(s32) = COPY $w0
367 %undef:_(<4 x s32>) = G_IMPLICIT_DEF
368 %buildvec:_(<4 x s32>) = G_BUILD_VECTOR %lane, %b, %c, %d
369 %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %buildvec(<4 x s32>), %undef, shufflemask(0, 0, 0, 0)
370 $q0 = COPY %shuf(<4 x s32>)
371 RET_ReallyLR implicit $q0