[WinEH] Add some test cases I forgot to add to previous commits
[oota-llvm.git] / test / CodeGen / AArch64 / fp16-vector-shuffle.ll
1 ; RUN: llc < %s -mtriple=aarch64-none-eabi | FileCheck %s
2
3 ; float16x4_t select_64(float16x4_t a, float16x4_t b, uint16x4_t c) { return vbsl_u16(c, a, b); }
4 define <4 x half> @select_64(<4 x half> %a, <4 x half> %b, <4 x i16> %c) #0 {
5 ; CHECK-LABEL: select_64:
6 ; CHECK: bsl
7 entry:
8   %0 = bitcast <4 x half> %a to <4 x i16>
9   %1 = bitcast <4 x half> %b to <4 x i16>
10   %vbsl3.i = and <4 x i16> %0, %c
11   %2 = xor <4 x i16> %c, <i16 -1, i16 -1, i16 -1, i16 -1>
12   %vbsl4.i = and <4 x i16> %1, %2
13   %vbsl5.i = or <4 x i16> %vbsl3.i, %vbsl4.i
14   %3 = bitcast <4 x i16> %vbsl5.i to <4 x half>
15   ret <4 x half> %3
16 }
17
18 ; float16x8_t select_128(float16x8_t a, float16x8_t b, uint16x8_t c) { return vbslq_u16(c, a, b); }
19 define <8 x half> @select_128(<8 x half> %a, <8 x half> %b, <8 x i16> %c) #0 {
20 ; CHECK-LABEL: select_128:
21 ; CHECK: bsl
22 entry:
23   %0 = bitcast <8 x half> %a to <8 x i16>
24   %1 = bitcast <8 x half> %b to <8 x i16>
25   %vbsl3.i = and <8 x i16> %0, %c
26   %2 = xor <8 x i16> %c, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
27   %vbsl4.i = and <8 x i16> %1, %2
28   %vbsl5.i = or <8 x i16> %vbsl3.i, %vbsl4.i
29   %3 = bitcast <8 x i16> %vbsl5.i to <8 x half>
30   ret <8 x half> %3
31 }
32
33 ; float16x4_t lane_64_64(float16x4_t a, float16x4_t b) {
34 ;  return vcopy_lane_s16(a, 1, b, 2);
35 ; }
36 define <4 x half> @lane_64_64(<4 x half> %a, <4 x half> %b) #0 {
37 ; CHECK-LABEL: lane_64_64:
38 ; CHECK: ins
39 entry:
40   %0 = shufflevector <4 x half> %a, <4 x half> %b, <4 x i32> <i32 0, i32 6, i32 2, i32 3>
41   ret <4 x half> %0
42 }
43
44 ; float16x8_t lane_128_64(float16x8_t a, float16x4_t b) {
45 ;   return vcopyq_lane_s16(a, 1, b, 2);
46 ; }
47 define <8 x half> @lane_128_64(<8 x half> %a, <4 x half> %b) #0 {
48 ; CHECK-LABEL: lane_128_64:
49 ; CHECK: ins
50 entry:
51   %0 = bitcast <4 x half> %b to <4 x i16>
52   %vget_lane = extractelement <4 x i16> %0, i32 2
53   %1 = bitcast <8 x half> %a to <8 x i16>
54   %vset_lane = insertelement <8 x i16> %1, i16 %vget_lane, i32 1
55   %2 = bitcast <8 x i16> %vset_lane to <8 x half>
56   ret <8 x half> %2
57 }
58
59 ; float16x4_t lane_64_128(float16x4_t a, float16x8_t b) {
60 ;   return vcopy_laneq_s16(a, 3, b, 5);
61 ; }
62 define <4 x half> @lane_64_128(<4 x half> %a, <8 x half> %b) #0 {
63 ; CHECK-LABEL: lane_64_128:
64 ; CHECK: ins
65 entry:
66   %0 = bitcast <8 x half> %b to <8 x i16>
67   %vgetq_lane = extractelement <8 x i16> %0, i32 5
68   %1 = bitcast <4 x half> %a to <4 x i16>
69   %vset_lane = insertelement <4 x i16> %1, i16 %vgetq_lane, i32 3
70   %2 = bitcast <4 x i16> %vset_lane to <4 x half>
71   ret <4 x half> %2
72 }
73
74 ; float16x8_t lane_128_128(float16x8_t a, float16x8_t b) {
75 ;   return vcopyq_laneq_s16(a, 3, b, 5);
76 ; }
77 define <8 x half> @lane_128_128(<8 x half> %a, <8 x half> %b) #0 {
78 ; CHECK-LABEL: lane_128_128:
79 ; CHECK: ins
80 entry:
81   %0 = shufflevector <8 x half> %a, <8 x half> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 13, i32 4, i32 5, i32 6, i32 7>
82   ret <8 x half> %0
83 }
84
85 ; float16x4_t ext_64(float16x4_t a, float16x4_t b) {
86 ;   return vext_s16(a, b, 3);
87 ; }
88 define <4 x half> @ext_64(<4 x half> %a, <4 x half> %b) #0 {
89 ; CHECK-LABEL: ext_64:
90 ; CHECK: ext
91 entry:
92   %0 = shufflevector <4 x half> %a, <4 x half> %b, <4 x i32> <i32 3, i32 4, i32 5, i32 6>
93   ret <4 x half> %0
94 }
95
96 ; float16x8_t ext_128(float16x8_t a, float16x8_t b) {
97 ;   return vextq_s16(a, b, 3);
98 ; }
99 define <8 x half> @ext_128(<8 x half> %a, <8 x half> %b) #0 {
100 ; CHECK-LABEL: ext_128:
101 ; CHECK: ext
102 entry:
103   %0 = shufflevector <8 x half> %a, <8 x half> %b, <8 x i32> <i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10>
104   ret <8 x half> %0
105 }
106
107 ; float16x4_t rev32_64(float16x4_t a) {
108 ;   return vrev32_s16(a);
109 ; }
110 define <4 x half> @rev32_64(<4 x half> %a) #0 {
111 entry:
112 ; CHECK-LABEL: rev32_64:
113 ; CHECK: rev32
114   %0 = shufflevector <4 x half> %a, <4 x half> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
115   ret <4 x half> %0
116 }
117
118 ; float16x4_t rev64_64(float16x4_t a) {
119 ;   return vrev64_s16(a);
120 ; }
121 define <4 x half> @rev64_64(<4 x half> %a) #0 {
122 entry:
123 ; CHECK-LABEL: rev64_64:
124 ; CHECK: rev64
125   %0 = shufflevector <4 x half> %a, <4 x half> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
126   ret <4 x half> %0
127 }
128
129 ; float16x8_t rev32_128(float16x8_t a) {
130 ;   return vrev32q_s16(a);
131 ; }
132 define <8 x half> @rev32_128(<8 x half> %a) #0 {
133 entry:
134 ; CHECK-LABEL: rev32_128:
135 ; CHECK: rev32
136   %0 = shufflevector <8 x half> %a, <8 x half> undef, <8 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
137   ret <8 x half> %0
138 }
139
140 ; float16x8_t rev64_128(float16x8_t a) {
141 ;   return vrev64q_s16(a);
142 ; }
143 define <8 x half> @rev64_128(<8 x half> %a) #0 {
144 entry:
145 ; CHECK-LABEL: rev64_128:
146 ; CHECK: rev64
147   %0 = shufflevector <8 x half> %a, <8 x half> undef, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
148   ret <8 x half> %0
149 }
150
151 ; float16x4_t create_64(long long a) { return vcreate_f16(a); }
152 define <4 x half> @create_64(i64 %a) #0 {
153 ; CHECK-LABEL: create_64:
154 ; CHECK: fmov
155 entry:
156   %0 = bitcast i64 %a to <4 x half>
157   ret <4 x half> %0
158 }
159
160 ; float16x4_t dup_64(__fp16 a) { return vdup_n_f16(a); }
161 define <4 x half> @dup_64(half %a) #0 {
162 ; CHECK-LABEL: dup_64:
163 ; CHECK: dup
164 entry:
165   %vecinit = insertelement <4 x half> undef, half %a, i32 0
166   %vecinit1 = insertelement <4 x half> %vecinit, half %a, i32 1
167   %vecinit2 = insertelement <4 x half> %vecinit1, half %a, i32 2
168   %vecinit3 = insertelement <4 x half> %vecinit2, half %a, i32 3
169   ret <4 x half> %vecinit3
170 }
171
172 ; float16x8_t dup_128(__fp16 a) { return vdupq_n_f16(a); }
173 define <8 x half> @dup_128(half %a) #0 {
174 entry:
175 ; CHECK-LABEL: dup_128:
176 ; CHECK: dup
177   %vecinit = insertelement <8 x half> undef, half %a, i32 0
178   %vecinit1 = insertelement <8 x half> %vecinit, half %a, i32 1
179   %vecinit2 = insertelement <8 x half> %vecinit1, half %a, i32 2
180   %vecinit3 = insertelement <8 x half> %vecinit2, half %a, i32 3
181   %vecinit4 = insertelement <8 x half> %vecinit3, half %a, i32 4
182   %vecinit5 = insertelement <8 x half> %vecinit4, half %a, i32 5
183   %vecinit6 = insertelement <8 x half> %vecinit5, half %a, i32 6
184   %vecinit7 = insertelement <8 x half> %vecinit6, half %a, i32 7
185   ret <8 x half> %vecinit7
186 }
187
188 ; float16x4_t dup_lane_64(float16x4_t a) { return vdup_lane_f16(a, 2); }
189 define <4 x half> @dup_lane_64(<4 x half> %a) #0 {
190 entry:
191 ; CHECK-LABEL: dup_lane_64:
192 ; CHECK: dup
193   %shuffle = shufflevector <4 x half> %a, <4 x half> undef, <4 x i32> <i32 2, i32 2, i32 2, i32 2>
194   ret <4 x half> %shuffle
195 }
196
197 ; float16x8_t dup_lane_128(float16x4_t a) { return vdupq_lane_f16(a, 2); }
198 define <8 x half> @dup_lane_128(<4 x half> %a) #0 {
199 entry:
200 ; CHECK-LABEL: dup_lane_128:
201 ; CHECK: dup
202   %shuffle = shufflevector <4 x half> %a, <4 x half> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
203   ret <8 x half> %shuffle
204 }
205
206 ; float16x4_t dup_laneq_64(float16x8_t a) { return vdup_laneq_f16(a, 2); }
207 define <4 x half> @dup_laneq_64(<8 x half> %a) #0 {
208 entry:
209 ; CHECK-LABEL: dup_laneq_64:
210 ; CHECK: dup
211   %shuffle = shufflevector <8 x half> %a, <8 x half> undef, <4 x i32> <i32 2, i32 2, i32 2, i32 2>
212   ret <4 x half> %shuffle
213 }
214
215 ; float16x8_t dup_laneq_128(float16x8_t a) { return vdupq_laneq_f16(a, 2); }
216 define <8 x half> @dup_laneq_128(<8 x half> %a) #0 {
217 entry:
218 ; CHECK-LABEL: dup_laneq_128:
219 ; CHECK: dup
220   %shuffle = shufflevector <8 x half> %a, <8 x half> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
221   ret <8 x half> %shuffle
222 }
223
224 ; float16x8_t vcombine(float16x4_t a, float16x4_t b) { return vcombine_f16(a, b); }
225 define <8 x half> @vcombine(<4 x half> %a, <4 x half> %b) #0 {
226 entry:
227 ; CHECK-LABEL: vcombine:
228 ; CHECK: ins
229   %shuffle.i = shufflevector <4 x half> %a, <4 x half> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
230   ret <8 x half> %shuffle.i
231 }
232
233 ; float16x4_t get_high(float16x8_t a) { return vget_high_f16(a); }
234 define <4 x half> @get_high(<8 x half> %a) #0 {
235 ; CHECK-LABEL: get_high:
236 ; CHECK: ext
237 entry:
238   %shuffle.i = shufflevector <8 x half> %a, <8 x half> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
239   ret <4 x half> %shuffle.i
240 }
241
242
243 ; float16x4_t get_low(float16x8_t a) { return vget_low_f16(a); }
244 define <4 x half> @get_low(<8 x half> %a) #0 {
245 ; CHECK-LABEL: get_low:
246 ; CHECK-NOT: ext
247 entry:
248   %shuffle.i = shufflevector <8 x half> %a, <8 x half> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
249   ret <4 x half> %shuffle.i
250 }
251
252 ; float16x4_t set_lane_64(float16x4_t a, __fp16 b) { return vset_lane_f16(b, a, 2); }
253 define <4 x half> @set_lane_64(<4 x half> %a, half %b) #0 {
254 ; CHECK-LABEL: set_lane_64:
255 ; CHECK: fmov
256 ; CHECK: ins
257 entry:
258   %0 = bitcast half %b to i16
259   %1 = bitcast <4 x half> %a to <4 x i16>
260   %vset_lane = insertelement <4 x i16> %1, i16 %0, i32 2
261   %2 = bitcast <4 x i16> %vset_lane to <4 x half>
262   ret <4 x half> %2
263 }
264
265
266 ; float16x8_t set_lane_128(float16x8_t a, __fp16 b) { return vsetq_lane_f16(b, a, 2); }
267 define <8 x half> @set_lane_128(<8 x half> %a, half %b) #0 {
268 ; CHECK-LABEL: set_lane_128:
269 ; CHECK: fmov
270 ; CHECK: ins
271 entry:
272   %0 = bitcast half %b to i16
273   %1 = bitcast <8 x half> %a to <8 x i16>
274   %vset_lane = insertelement <8 x i16> %1, i16 %0, i32 2
275   %2 = bitcast <8 x i16> %vset_lane to <8 x half>
276   ret <8 x half> %2
277 }
278
279 ; __fp16 get_lane_64(float16x4_t a) { return vget_lane_f16(a, 2); }
280 define half @get_lane_64(<4 x half> %a) #0 {
281 ; CHECK-LABEL: get_lane_64:
282 ; CHECK: umov
283 ; CHECK: fmov
284 entry:
285   %0 = bitcast <4 x half> %a to <4 x i16>
286   %vget_lane = extractelement <4 x i16> %0, i32 2
287   %1 = bitcast i16 %vget_lane to half
288   ret half %1
289 }
290
291 ; __fp16 get_lane_128(float16x8_t a) { return vgetq_lane_f16(a, 2); }
292 define half @get_lane_128(<8 x half> %a) #0 {
293 ; CHECK-LABEL: get_lane_128:
294 ; CHECK: umov
295 ; CHECK: fmov
296 entry:
297   %0 = bitcast <8 x half> %a to <8 x i16>
298   %vgetq_lane = extractelement <8 x i16> %0, i32 2
299   %1 = bitcast i16 %vgetq_lane to half
300   ret half %1
301 }