[TTI] getTypeBasedIntrinsicInstrCost - add basic handling for strided load/store...
[llvm-project.git] / llvm / test / CodeGen / AArch64 / qshrn.ll
blob0212ff53b2503b19ca0ba58f2ac0896cc54a3c27
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2 ; RUN: llc %s -mtriple=aarch64 -o - | FileCheck %s
4 define <4 x i16> @NarrowAShrI32By5(<4 x i32> %x) {
5 ; CHECK-LABEL: NarrowAShrI32By5:
6 ; CHECK:       // %bb.0:
7 ; CHECK-NEXT:    sqshrn v0.4h, v0.4s, #5
8 ; CHECK-NEXT:    ret
9   %s = ashr <4 x i32> %x, <i32 5, i32 5, i32 5, i32 5>
10   %r = tail call <4 x i16> @llvm.aarch64.neon.sqxtn.v4i16(<4 x i32> %s)
11   ret <4 x i16> %r
14 define <4 x i16> @NarrowAShrU32By5(<4 x i32> %x) {
15 ; CHECK-LABEL: NarrowAShrU32By5:
16 ; CHECK:       // %bb.0:
17 ; CHECK-NEXT:    sshr v0.4s, v0.4s, #5
18 ; CHECK-NEXT:    uqxtn v0.4h, v0.4s
19 ; CHECK-NEXT:    ret
20   %s = ashr <4 x i32> %x, <i32 5, i32 5, i32 5, i32 5>
21   %r = tail call <4 x i16> @llvm.aarch64.neon.uqxtn.v4i16(<4 x i32> %s)
22   ret <4 x i16> %r
25 define <4 x i16> @NarrowAShrI32By5ToU16(<4 x i32> %x) {
26 ; CHECK-LABEL: NarrowAShrI32By5ToU16:
27 ; CHECK:       // %bb.0:
28 ; CHECK-NEXT:    sqshrun v0.4h, v0.4s, #5
29 ; CHECK-NEXT:    ret
30   %s = ashr <4 x i32> %x, <i32 5, i32 5, i32 5, i32 5>
31   %r = tail call <4 x i16> @llvm.aarch64.neon.sqxtun.v4i16(<4 x i32> %s)
32   ret <4 x i16> %r
35 define <4 x i16> @NarrowLShrI32By5(<4 x i32> %x) {
36 ; CHECK-LABEL: NarrowLShrI32By5:
37 ; CHECK:       // %bb.0:
38 ; CHECK-NEXT:    ushr v0.4s, v0.4s, #5
39 ; CHECK-NEXT:    sqxtn v0.4h, v0.4s
40 ; CHECK-NEXT:    ret
41   %s = lshr <4 x i32> %x, <i32 5, i32 5, i32 5, i32 5>
42   %r = tail call <4 x i16> @llvm.aarch64.neon.sqxtn.v4i16(<4 x i32> %s)
43   ret <4 x i16> %r
46 define <4 x i16> @NarrowLShrU32By5(<4 x i32> %x) {
47 ; CHECK-LABEL: NarrowLShrU32By5:
48 ; CHECK:       // %bb.0:
49 ; CHECK-NEXT:    uqshrn v0.4h, v0.4s, #5
50 ; CHECK-NEXT:    ret
51   %s = lshr <4 x i32> %x, <i32 5, i32 5, i32 5, i32 5>
52   %r = tail call <4 x i16> @llvm.aarch64.neon.uqxtn.v4i16(<4 x i32> %s)
53   ret <4 x i16> %r
56 define <4 x i16> @NarrowLShrI32By5ToU16(<4 x i32> %x) {
57 ; CHECK-LABEL: NarrowLShrI32By5ToU16:
58 ; CHECK:       // %bb.0:
59 ; CHECK-NEXT:    ushr v0.4s, v0.4s, #5
60 ; CHECK-NEXT:    sqxtun v0.4h, v0.4s
61 ; CHECK-NEXT:    ret
62   %s = lshr <4 x i32> %x, <i32 5, i32 5, i32 5, i32 5>
63   %r = tail call <4 x i16> @llvm.aarch64.neon.sqxtun.v4i16(<4 x i32> %s)
64   ret <4 x i16> %r
68 define <2 x i32> @NarrowAShri64By5(<2 x i64> %x) {
69 ; CHECK-LABEL: NarrowAShri64By5:
70 ; CHECK:       // %bb.0:
71 ; CHECK-NEXT:    sqshrn v0.2s, v0.2d, #5
72 ; CHECK-NEXT:    ret
73   %s = ashr <2 x i64> %x, <i64 5, i64 5>
74   %r = tail call <2 x i32> @llvm.aarch64.neon.sqxtn.v2i32(<2 x i64> %s)
75   ret <2 x i32> %r
78 define <2 x i32> @NarrowAShrU64By5(<2 x i64> %x) {
79 ; CHECK-LABEL: NarrowAShrU64By5:
80 ; CHECK:       // %bb.0:
81 ; CHECK-NEXT:    sshr v0.2d, v0.2d, #5
82 ; CHECK-NEXT:    uqxtn v0.2s, v0.2d
83 ; CHECK-NEXT:    ret
84   %s = ashr <2 x i64> %x, <i64 5, i64 5>
85   %r = tail call <2 x i32> @llvm.aarch64.neon.uqxtn.v2i32(<2 x i64> %s)
86   ret <2 x i32> %r
89 define <2 x i32> @NarrowAShri64By5ToU32(<2 x i64> %x) {
90 ; CHECK-LABEL: NarrowAShri64By5ToU32:
91 ; CHECK:       // %bb.0:
92 ; CHECK-NEXT:    sqshrun v0.2s, v0.2d, #5
93 ; CHECK-NEXT:    ret
94   %s = ashr <2 x i64> %x, <i64 5, i64 5>
95   %r = tail call <2 x i32> @llvm.aarch64.neon.sqxtun.v2i32(<2 x i64> %s)
96   ret <2 x i32> %r
99 define <2 x i32> @NarrowLShri64By5(<2 x i64> %x) {
100 ; CHECK-LABEL: NarrowLShri64By5:
101 ; CHECK:       // %bb.0:
102 ; CHECK-NEXT:    ushr v0.2d, v0.2d, #5
103 ; CHECK-NEXT:    sqxtn v0.2s, v0.2d
104 ; CHECK-NEXT:    ret
105   %s = lshr <2 x i64> %x, <i64 5, i64 5>
106   %r = tail call <2 x i32> @llvm.aarch64.neon.sqxtn.v2i32(<2 x i64> %s)
107   ret <2 x i32> %r
110 define <2 x i32> @NarrowLShrU64By5(<2 x i64> %x) {
111 ; CHECK-LABEL: NarrowLShrU64By5:
112 ; CHECK:       // %bb.0:
113 ; CHECK-NEXT:    uqshrn v0.2s, v0.2d, #5
114 ; CHECK-NEXT:    ret
115   %s = lshr <2 x i64> %x, <i64 5, i64 5>
116   %r = tail call <2 x i32> @llvm.aarch64.neon.uqxtn.v2i32(<2 x i64> %s)
117   ret <2 x i32> %r
120 define <2 x i32> @NarrowLShri64By5ToU32(<2 x i64> %x) {
121 ; CHECK-LABEL: NarrowLShri64By5ToU32:
122 ; CHECK:       // %bb.0:
123 ; CHECK-NEXT:    ushr v0.2d, v0.2d, #5
124 ; CHECK-NEXT:    sqxtun v0.2s, v0.2d
125 ; CHECK-NEXT:    ret
126   %s = lshr <2 x i64> %x, <i64 5, i64 5>
127   %r = tail call <2 x i32> @llvm.aarch64.neon.sqxtun.v2i32(<2 x i64> %s)
128   ret <2 x i32> %r
132 define <8 x i8> @NarrowAShri16By5(<8 x i16> %x) {
133 ; CHECK-LABEL: NarrowAShri16By5:
134 ; CHECK:       // %bb.0:
135 ; CHECK-NEXT:    sqshrn v0.8b, v0.8h, #5
136 ; CHECK-NEXT:    ret
137   %s = ashr <8 x i16> %x, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
138   %r = tail call <8 x i8> @llvm.aarch64.neon.sqxtn.v8i8(<8 x i16> %s)
139   ret <8 x i8> %r
142 define <8 x i8> @NarrowAShrU16By5(<8 x i16> %x) {
143 ; CHECK-LABEL: NarrowAShrU16By5:
144 ; CHECK:       // %bb.0:
145 ; CHECK-NEXT:    sshr v0.8h, v0.8h, #5
146 ; CHECK-NEXT:    uqxtn v0.8b, v0.8h
147 ; CHECK-NEXT:    ret
148   %s = ashr <8 x i16> %x, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
149   %r = tail call <8 x i8> @llvm.aarch64.neon.uqxtn.v8i8(<8 x i16> %s)
150   ret <8 x i8> %r
153 define <8 x i8> @NarrowAShri16By5ToU8(<8 x i16> %x) {
154 ; CHECK-LABEL: NarrowAShri16By5ToU8:
155 ; CHECK:       // %bb.0:
156 ; CHECK-NEXT:    sqshrun v0.8b, v0.8h, #5
157 ; CHECK-NEXT:    ret
158   %s = ashr <8 x i16> %x, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
159   %r = tail call <8 x i8> @llvm.aarch64.neon.sqxtun.v8i8(<8 x i16> %s)
160   ret <8 x i8> %r
163 define <8 x i8> @NarrowLShri16By5(<8 x i16> %x) {
164 ; CHECK-LABEL: NarrowLShri16By5:
165 ; CHECK:       // %bb.0:
166 ; CHECK-NEXT:    ushr v0.8h, v0.8h, #5
167 ; CHECK-NEXT:    sqxtn v0.8b, v0.8h
168 ; CHECK-NEXT:    ret
169   %s = lshr <8 x i16> %x, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
170   %r = tail call <8 x i8> @llvm.aarch64.neon.sqxtn.v8i8(<8 x i16> %s)
171   ret <8 x i8> %r
174 define <8 x i8> @NarrowLShrU16By5(<8 x i16> %x) {
175 ; CHECK-LABEL: NarrowLShrU16By5:
176 ; CHECK:       // %bb.0:
177 ; CHECK-NEXT:    uqshrn v0.8b, v0.8h, #5
178 ; CHECK-NEXT:    ret
179   %s = lshr <8 x i16> %x, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
180   %r = tail call <8 x i8> @llvm.aarch64.neon.uqxtn.v8i8(<8 x i16> %s)
181   ret <8 x i8> %r
184 define <8 x i8> @NarrowLShri16By5ToU8(<8 x i16> %x) {
185 ; CHECK-LABEL: NarrowLShri16By5ToU8:
186 ; CHECK:       // %bb.0:
187 ; CHECK-NEXT:    ushr v0.8h, v0.8h, #5
188 ; CHECK-NEXT:    sqxtun v0.8b, v0.8h
189 ; CHECK-NEXT:    ret
190   %s = lshr <8 x i16> %x, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
191   %r = tail call <8 x i8> @llvm.aarch64.neon.sqxtun.v8i8(<8 x i16> %s)
192   ret <8 x i8> %r
199 define <4 x i16> @NarrowAShrI32By31(<4 x i32> %x) {
200 ; CHECK-LABEL: NarrowAShrI32By31:
201 ; CHECK:       // %bb.0:
202 ; CHECK-NEXT:    sqshrn v0.4h, v0.4s, #16
203 ; CHECK-NEXT:    ret
204   %s = ashr <4 x i32> %x, <i32 16, i32 16, i32 16, i32 16>
205   %r = tail call <4 x i16> @llvm.aarch64.neon.sqxtn.v4i16(<4 x i32> %s)
206   ret <4 x i16> %r
209 define <4 x i16> @NarrowAShrI32By31ToU16(<4 x i32> %x) {
210 ; CHECK-LABEL: NarrowAShrI32By31ToU16:
211 ; CHECK:       // %bb.0:
212 ; CHECK-NEXT:    sqshrun v0.4h, v0.4s, #16
213 ; CHECK-NEXT:    ret
214   %s = ashr <4 x i32> %x, <i32 16, i32 16, i32 16, i32 16>
215   %r = tail call <4 x i16> @llvm.aarch64.neon.sqxtun.v4i16(<4 x i32> %s)
216   ret <4 x i16> %r
219 define <4 x i16> @NarrowLShrU32By31(<4 x i32> %x) {
220 ; CHECK-LABEL: NarrowLShrU32By31:
221 ; CHECK:       // %bb.0:
222 ; CHECK-NEXT:    uqshrn v0.4h, v0.4s, #16
223 ; CHECK-NEXT:    ret
224   %s = lshr <4 x i32> %x, <i32 16, i32 16, i32 16, i32 16>
225   %r = tail call <4 x i16> @llvm.aarch64.neon.uqxtn.v4i16(<4 x i32> %s)
226   ret <4 x i16> %r
230 define <16 x i8> @signed_minmax_v8i16_to_v16i8(<16 x i16> %x) {
231 ; CHECK-LABEL: signed_minmax_v8i16_to_v16i8:
232 ; CHECK:       // %bb.0: // %entry
233 ; CHECK-NEXT:    sqshrn v0.8b, v0.8h, #5
234 ; CHECK-NEXT:    sqshrn2 v0.16b, v1.8h, #5
235 ; CHECK-NEXT:    ret
236 entry:
237   %s = ashr <16 x i16> %x, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
238   %min = call <16 x i16> @llvm.smin.v8i16(<16 x i16> %s, <16 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>)
239   %max = call <16 x i16> @llvm.smax.v8i16(<16 x i16> %min, <16 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>)
240   %trunc = trunc <16 x i16> %max to <16 x i8>
241   ret <16 x i8> %trunc
244 define <16 x i8> @unsigned_minmax_v8i16_to_v16i8(<16 x i16> %x) {
245 ; CHECK-LABEL: unsigned_minmax_v8i16_to_v16i8:
246 ; CHECK:       // %bb.0: // %entry
247 ; CHECK-NEXT:    uqshrn v0.8b, v0.8h, #5
248 ; CHECK-NEXT:    uqshrn2 v0.16b, v1.8h, #5
249 ; CHECK-NEXT:    ret
250 entry:
251   %s = lshr <16 x i16> %x, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
252   %min = call <16 x i16> @llvm.umin.v8i16(<16 x i16> %s, <16 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)
253   %trunc = trunc <16 x i16> %min to <16 x i8>
254   ret <16 x i8> %trunc
257 define <16 x i8> @unsigned_signed_minmax_v8i16_to_v16i8(<16 x i16> %x) {
258 ; CHECK-LABEL: unsigned_signed_minmax_v8i16_to_v16i8:
259 ; CHECK:       // %bb.0: // %entry
260 ; CHECK-NEXT:    sqshrun v0.8b, v0.8h, #5
261 ; CHECK-NEXT:    sqshrun2 v0.16b, v1.8h, #5
262 ; CHECK-NEXT:    ret
263 entry:
264   %s = ashr <16 x i16> %x, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
265   %max = call <16 x i16> @llvm.smax.v8i16(<16 x i16> %s, <16 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
266   %min = call <16 x i16> @llvm.umin.v8i16(<16 x i16> %max, <16 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)
267   %trunc = trunc <16 x i16> %min to <16 x i8>
268   ret <16 x i8> %trunc
272 define <8 x i16> @signed_minmax_v4i32_to_v8i16(<8 x i32> %x) {
273 ; CHECK-LABEL: signed_minmax_v4i32_to_v8i16:
274 ; CHECK:       // %bb.0: // %entry
275 ; CHECK-NEXT:    sqshrn v0.4h, v0.4s, #5
276 ; CHECK-NEXT:    sqshrn2 v0.8h, v1.4s, #5
277 ; CHECK-NEXT:    ret
278 entry:
279   %s = ashr <8 x i32> %x, <i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5>
280   %min = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %s, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>)
281   %max = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %min, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
282   %trunc = trunc <8 x i32> %max to <8 x i16>
283   ret <8 x i16> %trunc
286 define <8 x i16> @unsigned_minmax_v4i32_to_v8i16(<8 x i32> %x) {
287 ; CHECK-LABEL: unsigned_minmax_v4i32_to_v8i16:
288 ; CHECK:       // %bb.0: // %entry
289 ; CHECK-NEXT:    uqshrn v0.4h, v0.4s, #5
290 ; CHECK-NEXT:    uqshrn2 v0.8h, v1.4s, #5
291 ; CHECK-NEXT:    ret
292 entry:
293   %s = lshr <8 x i32> %x, <i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5>
294   %min = call <8 x i32> @llvm.umin.v8i32(<8 x i32> %s, <8 x i32> <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>)
295   %trunc = trunc <8 x i32> %min to <8 x i16>
296   ret <8 x i16> %trunc
299 define <8 x i16> @unsigned_signed_minmax_v4i32_to_v8i16(<8 x i32> %x) {
300 ; CHECK-LABEL: unsigned_signed_minmax_v4i32_to_v8i16:
301 ; CHECK:       // %bb.0: // %entry
302 ; CHECK-NEXT:    sqshrun v0.4h, v0.4s, #5
303 ; CHECK-NEXT:    sqshrun2 v0.8h, v1.4s, #5
304 ; CHECK-NEXT:    ret
305 entry:
306   %s = ashr <8 x i32> %x, <i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5>
307   %max = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %s, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>)
308   %min = call <8 x i32> @llvm.umin.v8i32(<8 x i32> %max, <8 x i32> <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>)
309   %trunc = trunc <8 x i32> %min to <8 x i16>
310   ret <8 x i16> %trunc
314 define <4 x i32> @signed_minmax_v4i64_to_v8i32(<4 x i64> %x) {
315 ; CHECK-LABEL: signed_minmax_v4i64_to_v8i32:
316 ; CHECK:       // %bb.0: // %entry
317 ; CHECK-NEXT:    sqshrn v0.2s, v0.2d, #5
318 ; CHECK-NEXT:    sqshrn2 v0.4s, v1.2d, #5
319 ; CHECK-NEXT:    ret
320 entry:
321   %s = ashr <4 x i64> %x, <i64 5, i64 5, i64 5, i64 5>
322   %min = call <4 x i64> @llvm.smin.v8i64(<4 x i64> %s, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)
323   %max = call <4 x i64> @llvm.smax.v8i64(<4 x i64> %min, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)
324   %trunc = trunc <4 x i64> %max to <4 x i32>
325   ret <4 x i32> %trunc
328 define <4 x i32> @unsigned_minmax_v4i64_to_v8i32(<4 x i64> %x) {
329 ; CHECK-LABEL: unsigned_minmax_v4i64_to_v8i32:
330 ; CHECK:       // %bb.0: // %entry
331 ; CHECK-NEXT:    uqshrn v0.2s, v0.2d, #5
332 ; CHECK-NEXT:    uqshrn2 v0.4s, v1.2d, #5
333 ; CHECK-NEXT:    ret
334 entry:
335   %s = lshr <4 x i64> %x, <i64 5, i64 5, i64 5, i64 5>
336   %min = call <4 x i64> @llvm.umin.v8i64(<4 x i64> %s, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>)
337   %trunc = trunc <4 x i64> %min to <4 x i32>
338   ret <4 x i32> %trunc
341 define <4 x i32> @unsigned_signed_minmax_v4i64_to_v8i32(<4 x i64> %x) {
342 ; CHECK-LABEL: unsigned_signed_minmax_v4i64_to_v8i32:
343 ; CHECK:       // %bb.0: // %entry
344 ; CHECK-NEXT:    sqshrun v0.2s, v0.2d, #5
345 ; CHECK-NEXT:    sqshrun2 v0.4s, v1.2d, #5
346 ; CHECK-NEXT:    ret
347 entry:
348   %s = ashr <4 x i64> %x, <i64 5, i64 5, i64 5, i64 5>
349   %max = call <4 x i64> @llvm.smax.v8i64(<4 x i64> %s, <4 x i64> <i64 0, i64 0, i64 0, i64 0>)
350   %min = call <4 x i64> @llvm.umin.v8i64(<4 x i64> %max, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>)
351   %trunc = trunc <4 x i64> %min to <4 x i32>
352   ret <4 x i32> %trunc