blob: f7f143ff49e31ab5254c459868ac8a1cf2a09cbe [file] [log] [blame]
John Brawn95886522018-10-25 15:31:51 +00001; RUN: llc < %s -mtriple=aarch64 | FileCheck %s
2
3; Tests of shufflevector where the index operand is half the width of the vector
4; operands. We should get one ext instruction and not two.
5
6; i8 tests
7define <8 x i8> @i8_off0(<16 x i8> %arg1, <16 x i8> %arg2) {
8; CHECK-LABEL: i8_off0:
9; CHECK-NOT: mov
10; CHECK-NOT: ext
11; CHECK: ret
12entry:
13 %shuffle = shufflevector <16 x i8> %arg1, <16 x i8> %arg2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
14 ret <8 x i8> %shuffle
15}
16
17define <8 x i8> @i8_off1(<16 x i8> %arg1, <16 x i8> %arg2) {
18; CHECK-LABEL: i8_off1:
19; CHECK-NOT: mov
20; CHECK: ext v0.16b, v0.16b, v0.16b, #1
21; CHECK-NOT: ext
22; CHECK: ret
23entry:
24 %shuffle = shufflevector <16 x i8> %arg1, <16 x i8> %arg2, <8 x i32> <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8>
25 ret <8 x i8> %shuffle
26}
27
28define <8 x i8> @i8_off8(<16 x i8> %arg1, <16 x i8> %arg2) {
29; CHECK-LABEL: i8_off8:
30; CHECK-NOT: mov
31; CHECK: ext v0.16b, v0.16b, v0.16b, #8
32; CHECK-NOT: ext
33; CHECK: ret
34entry:
35 %shuffle = shufflevector <16 x i8> %arg1, <16 x i8> %arg2, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
36 ret <8 x i8> %shuffle
37}
38
39define <8 x i8> @i8_off15(<16 x i8> %arg1, <16 x i8> %arg2) {
40; CHECK-LABEL: i8_off15:
41; CHECK: ext v0.16b, v0.16b, v1.16b, #15
42; CHECK-NOT: ext
43; CHECK: ret
44entry:
45 %shuffle = shufflevector <16 x i8> %arg1, <16 x i8> %arg2, <8 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22>
46 ret <8 x i8> %shuffle
47}
48
49define <8 x i8> @i8_off22(<16 x i8> %arg1, <16 x i8> %arg2) {
50; CHECK-LABEL: i8_off22:
51; CHECK: ext v0.16b, v1.16b, v1.16b, #6
52; CHECK-NOT: ext
53; CHECK: ret
54entry:
55 %shuffle = shufflevector <16 x i8> %arg1, <16 x i8> %arg2, <8 x i32> <i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29>
56 ret <8 x i8> %shuffle
57}
58
59; i16 tests
60define <4 x i16> @i16_off0(<8 x i16> %arg1, <8 x i16> %arg2) {
61; CHECK-LABEL: i16_off0:
62; CHECK-NOT: mov
63; CHECK-NOT: ext
64; CHECK: ret
65entry:
66 %shuffle = shufflevector <8 x i16> %arg1, <8 x i16> %arg2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
67 ret <4 x i16> %shuffle
68}
69
70define <4 x i16> @i16_off1(<8 x i16> %arg1, <8 x i16> %arg2) {
71; CHECK-LABEL: i16_off1:
72; CHECK-NOT: mov
73; CHECK: ext v0.16b, v0.16b, v0.16b, #2
74; CHECK-NOT: ext
75; CHECK: ret
76entry:
77 %shuffle = shufflevector <8 x i16> %arg1, <8 x i16> %arg2, <4 x i32> <i32 1, i32 2, i32 3, i32 4>
78 ret <4 x i16> %shuffle
79}
80
81define <4 x i16> @i16_off7(<8 x i16> %arg1, <8 x i16> %arg2) {
82; CHECK-LABEL: i16_off7:
83; CHECK: ext v0.16b, v0.16b, v1.16b, #14
84; CHECK-NOT: ext
85; CHECK: ret
86entry:
87 %shuffle = shufflevector <8 x i16> %arg1, <8 x i16> %arg2, <4 x i32> <i32 7, i32 8, i32 9, i32 10>
88 ret <4 x i16> %shuffle
89}
90
91define <4 x i16> @i16_off8(<8 x i16> %arg1, <8 x i16> %arg2) {
92; CHECK-LABEL: i16_off8:
93; CHECK: mov v0.16b, v1.16b
94; CHECK-NOT: ext
95; CHECK: ret
96entry:
97 %shuffle = shufflevector <8 x i16> %arg1, <8 x i16> %arg2, <4 x i32> <i32 8, i32 9, i32 10, i32 11>
98 ret <4 x i16> %shuffle
99}
100
101; i32 tests
102define <2 x i32> @i32_off0(<4 x i32> %arg1, <4 x i32> %arg2) {
103; CHECK-LABEL: i32_off0:
104; CHECK-NOT: mov
105; CHECK-NOT: ext
106; CHECK: ret
107entry:
108 %shuffle = shufflevector <4 x i32> %arg1, <4 x i32> %arg2, <2 x i32> <i32 0, i32 1>
109 ret <2 x i32> %shuffle
110}
111
112define <2 x i32> @i32_off1(<4 x i32> %arg1, <4 x i32> %arg2) {
113; CHECK-LABEL: i32_off1:
114; CHECK-NOT: mov
115; CHECK: ext v0.16b, v0.16b, v0.16b, #4
116; CHECK-NOT: ext
117; CHECK: ret
118entry:
119 %shuffle = shufflevector <4 x i32> %arg1, <4 x i32> %arg2, <2 x i32> <i32 1, i32 2>
120 ret <2 x i32> %shuffle
121}
122
123define <2 x i32> @i32_off3(<4 x i32> %arg1, <4 x i32> %arg2) {
124; CHECK-LABEL: i32_off3:
125; CHECK: ext v0.16b, v0.16b, v1.16b, #12
126; CHECK-NOT: ext
127; CHECK: ret
128entry:
129 %shuffle = shufflevector <4 x i32> %arg1, <4 x i32> %arg2, <2 x i32> <i32 3, i32 4>
130 ret <2 x i32> %shuffle
131}
132
133define <2 x i32> @i32_off4(<4 x i32> %arg1, <4 x i32> %arg2) {
134; CHECK-LABEL: i32_off4:
135; CHECK: mov v0.16b, v1.16b
136; CHECK-NOT: ext
137; CHECK: ret
138entry:
139 %shuffle = shufflevector <4 x i32> %arg1, <4 x i32> %arg2, <2 x i32> <i32 4, i32 5>
140 ret <2 x i32> %shuffle
141}
142
143; i64 tests
144define <1 x i64> @i64_off0(<2 x i64> %arg1, <2 x i64> %arg2) {
145; CHECK-LABEL: i64_off0:
146; CHECK-NOT: mov
147; CHECK-NOT: ext
148; CHECK: ret
149entry:
150 %shuffle = shufflevector <2 x i64> %arg1, <2 x i64> %arg2, <1 x i32> <i32 0>
151 ret <1 x i64> %shuffle
152}
153
154define <1 x i64> @i64_off1(<2 x i64> %arg1, <2 x i64> %arg2) {
155; CHECK-LABEL: i64_off1:
156; CHECK-NOT: mov
157; CHECK: ext v0.16b, v0.16b, v0.16b, #8
158; CHECK-NOT: ext
159; CHECK: ret
160entry:
161 %shuffle = shufflevector <2 x i64> %arg1, <2 x i64> %arg2, <1 x i32> <i32 1>
162 ret <1 x i64> %shuffle
163}
164
165define <1 x i64> @i64_off2(<2 x i64> %arg1, <2 x i64> %arg2) {
166; CHECK-LABEL: i64_off2:
167; CHECK: mov v0.16b, v1.16b
168; CHECK-NOT: ext
169; CHECK: ret
170entry:
171 %shuffle = shufflevector <2 x i64> %arg1, <2 x i64> %arg2, <1 x i32> <i32 2>
172 ret <1 x i64> %shuffle
173}
174
175; i8 tests with second operand zero
176define <8 x i8> @i8_zero_off0(<16 x i8> %arg1) {
177; CHECK-LABEL: i8_zero_off0:
178; CHECK-NOT: mov
179; CHECK-NOT: ext
180; CHECK: ret
181entry:
182 %shuffle = shufflevector <16 x i8> %arg1, <16 x i8> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
183 ret <8 x i8> %shuffle
184}
185
186define <8 x i8> @i8_zero_off1(<16 x i8> %arg1) {
187; CHECK-LABEL: i8_zero_off1:
188; CHECK-NOT: mov
189; CHECK: ext v0.16b, v0.16b, v0.16b, #1
190; CHECK-NOT: ext
191; CHECK: ret
192entry:
193 %shuffle = shufflevector <16 x i8> %arg1, <16 x i8> zeroinitializer, <8 x i32> <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8>
194 ret <8 x i8> %shuffle
195}
196
197define <8 x i8> @i8_zero_off8(<16 x i8> %arg1) {
198; CHECK-LABEL: i8_zero_off8:
199; CHECK-NOT: mov
200; CHECK: ext v0.16b, v0.16b, v0.16b, #8
201; CHECK-NOT: ext
202; CHECK: ret
203entry:
204 %shuffle = shufflevector <16 x i8> %arg1, <16 x i8> zeroinitializer, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
205 ret <8 x i8> %shuffle
206}
207
208define <8 x i8> @i8_zero_off15(<16 x i8> %arg1) {
209; CHECK-LABEL: i8_zero_off15:
210; CHECK: movi [[REG:v[0-9]+]].2d, #0
211; CHECK: ext v0.16b, v0.16b, [[REG]].16b, #15
212; CHECK-NOT: ext
213; CHECK: ret
214entry:
215 %shuffle = shufflevector <16 x i8> %arg1, <16 x i8> zeroinitializer, <8 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22>
216 ret <8 x i8> %shuffle
217}
218
219define <8 x i8> @i8_zero_off22(<16 x i8> %arg1) {
220; CHECK-LABEL: i8_zero_off22:
221; CHECK: movi v0.2d, #0
222; CHECK-NOT: ext
223; CHECK: ret
224entry:
225 %shuffle = shufflevector <16 x i8> %arg1, <16 x i8> zeroinitializer, <8 x i32> <i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29>
226 ret <8 x i8> %shuffle
227}
228
229; i16 tests with second operand zero
230define <4 x i16> @i16_zero_off0(<8 x i16> %arg1) {
231; CHECK-LABEL: i16_zero_off0:
232; CHECK-NOT: mov
233; CHECK-NOT: ext
234; CHECK: ret
235entry:
236 %shuffle = shufflevector <8 x i16> %arg1, <8 x i16> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
237 ret <4 x i16> %shuffle
238}
239
240define <4 x i16> @i16_zero_off1(<8 x i16> %arg1) {
241; CHECK-LABEL: i16_zero_off1:
242; CHECK-NOT: mov
243; CHECK: ext v0.16b, v0.16b, v0.16b, #2
244; CHECK-NOT: ext
245; CHECK: ret
246entry:
247 %shuffle = shufflevector <8 x i16> %arg1, <8 x i16> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 4>
248 ret <4 x i16> %shuffle
249}
250
251define <4 x i16> @i16_zero_off7(<8 x i16> %arg1) {
252; CHECK-LABEL: i16_zero_off7:
253; CHECK: movi [[REG:v[0-9]+]].2d, #0
254; CHECK: ext v0.16b, v0.16b, [[REG]].16b, #14
255; CHECK-NOT: ext
256; CHECK: ret
257entry:
258 %shuffle = shufflevector <8 x i16> %arg1, <8 x i16> zeroinitializer, <4 x i32> <i32 7, i32 8, i32 9, i32 10>
259 ret <4 x i16> %shuffle
260}
261
262define <4 x i16> @i16_zero_off8(<8 x i16> %arg1) {
263; CHECK-LABEL: i16_zero_off8:
264; CHECK: movi v0.2d, #0
265; CHECK-NOT: ext
266; CHECK: ret
267entry:
268 %shuffle = shufflevector <8 x i16> %arg1, <8 x i16> zeroinitializer, <4 x i32> <i32 8, i32 9, i32 10, i32 11>
269 ret <4 x i16> %shuffle
270}
271
272; i32 tests with second operand zero
273define <2 x i32> @i32_zero_off0(<4 x i32> %arg1) {
274; CHECK-LABEL: i32_zero_off0:
275; CHECK-NOT: mov
276; CHECK-NOT: ext
277; CHECK: ret
278entry:
279 %shuffle = shufflevector <4 x i32> %arg1, <4 x i32> zeroinitializer, <2 x i32> <i32 0, i32 1>
280 ret <2 x i32> %shuffle
281}
282
283define <2 x i32> @i32_zero_off1(<4 x i32> %arg1) {
284; CHECK-LABEL: i32_zero_off1:
285; CHECK-NOT: mov
286; CHECK: ext v0.16b, v0.16b, v0.16b, #4
287; CHECK-NOT: ext
288; CHECK: ret
289entry:
290 %shuffle = shufflevector <4 x i32> %arg1, <4 x i32> zeroinitializer, <2 x i32> <i32 1, i32 2>
291 ret <2 x i32> %shuffle
292}
293
294define <2 x i32> @i32_zero_off3(<4 x i32> %arg1) {
295; CHECK-LABEL: i32_zero_off3:
296; CHECK: movi [[REG:v[0-9]+]].2d, #0
297; CHECK: ext v0.16b, v0.16b, [[REG]].16b, #12
298; CHECK-NOT: ext
299; CHECK: ret
300entry:
301 %shuffle = shufflevector <4 x i32> %arg1, <4 x i32> zeroinitializer, <2 x i32> <i32 3, i32 4>
302 ret <2 x i32> %shuffle
303}
304
305define <2 x i32> @i32_zero_off4(<4 x i32> %arg1) {
306; CHECK-LABEL: i32_zero_off4:
307; CHECK: movi v0.2d, #0
308; CHECK-NOT: ext
309; CHECK: ret
310entry:
311 %shuffle = shufflevector <4 x i32> %arg1, <4 x i32> zeroinitializer, <2 x i32> <i32 4, i32 5>
312 ret <2 x i32> %shuffle
313}
314
315; i64 tests with second operand zero
316define <1 x i64> @i64_zero_off0(<2 x i64> %arg1) {
317; CHECK-LABEL: i64_zero_off0:
318; CHECK-NOT: mov
319; CHECK-NOT: ext
320; CHECK: ret
321entry:
322 %shuffle = shufflevector <2 x i64> %arg1, <2 x i64> zeroinitializer, <1 x i32> <i32 0>
323 ret <1 x i64> %shuffle
324}
325
326define <1 x i64> @i64_zero_off1(<2 x i64> %arg1) {
327; CHECK-LABEL: i64_zero_off1:
328; CHECK-NOT: mov
329; CHECK: ext v0.16b, v0.16b, v0.16b, #8
330; CHECK-NOT: ext
331; CHECK: ret
332entry:
333 %shuffle = shufflevector <2 x i64> %arg1, <2 x i64> zeroinitializer, <1 x i32> <i32 1>
334 ret <1 x i64> %shuffle
335}
336
337define <1 x i64> @i64_zero_off2(<2 x i64> %arg1) {
338; CHECK-LABEL: i64_zero_off2:
339; CHECK: fmov d0, xzr
340; CHECK-NOT: ext
341; CHECK: ret
342entry:
343 %shuffle = shufflevector <2 x i64> %arg1, <2 x i64> zeroinitializer, <1 x i32> <i32 2>
344 ret <1 x i64> %shuffle
345}