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:
7 ; CHECK-NEXT: sqshrn v0.4h, v0.4s, #5
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)
14 define <4 x i16> @NarrowAShrU32By5(<4 x i32> %x) {
15 ; CHECK-LABEL: NarrowAShrU32By5:
17 ; CHECK-NEXT: sshr v0.4s, v0.4s, #5
18 ; CHECK-NEXT: uqxtn v0.4h, v0.4s
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)
25 define <4 x i16> @NarrowAShrI32By5ToU16(<4 x i32> %x) {
26 ; CHECK-LABEL: NarrowAShrI32By5ToU16:
28 ; CHECK-NEXT: sqshrun v0.4h, v0.4s, #5
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)
35 define <4 x i16> @NarrowLShrI32By5(<4 x i32> %x) {
36 ; CHECK-LABEL: NarrowLShrI32By5:
38 ; CHECK-NEXT: ushr v0.4s, v0.4s, #5
39 ; CHECK-NEXT: sqxtn v0.4h, v0.4s
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)
46 define <4 x i16> @NarrowLShrU32By5(<4 x i32> %x) {
47 ; CHECK-LABEL: NarrowLShrU32By5:
49 ; CHECK-NEXT: uqshrn v0.4h, v0.4s, #5
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)
56 define <4 x i16> @NarrowLShrI32By5ToU16(<4 x i32> %x) {
57 ; CHECK-LABEL: NarrowLShrI32By5ToU16:
59 ; CHECK-NEXT: ushr v0.4s, v0.4s, #5
60 ; CHECK-NEXT: sqxtun v0.4h, v0.4s
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)
68 define <2 x i32> @NarrowAShri64By5(<2 x i64> %x) {
69 ; CHECK-LABEL: NarrowAShri64By5:
71 ; CHECK-NEXT: sqshrn v0.2s, v0.2d, #5
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)
78 define <2 x i32> @NarrowAShrU64By5(<2 x i64> %x) {
79 ; CHECK-LABEL: NarrowAShrU64By5:
81 ; CHECK-NEXT: sshr v0.2d, v0.2d, #5
82 ; CHECK-NEXT: uqxtn v0.2s, v0.2d
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)
89 define <2 x i32> @NarrowAShri64By5ToU32(<2 x i64> %x) {
90 ; CHECK-LABEL: NarrowAShri64By5ToU32:
92 ; CHECK-NEXT: sqshrun v0.2s, v0.2d, #5
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)
99 define <2 x i32> @NarrowLShri64By5(<2 x i64> %x) {
100 ; CHECK-LABEL: NarrowLShri64By5:
102 ; CHECK-NEXT: ushr v0.2d, v0.2d, #5
103 ; CHECK-NEXT: sqxtn v0.2s, v0.2d
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)
110 define <2 x i32> @NarrowLShrU64By5(<2 x i64> %x) {
111 ; CHECK-LABEL: NarrowLShrU64By5:
113 ; CHECK-NEXT: uqshrn v0.2s, v0.2d, #5
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)
120 define <2 x i32> @NarrowLShri64By5ToU32(<2 x i64> %x) {
121 ; CHECK-LABEL: NarrowLShri64By5ToU32:
123 ; CHECK-NEXT: ushr v0.2d, v0.2d, #5
124 ; CHECK-NEXT: sqxtun v0.2s, v0.2d
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)
132 define <8 x i8> @NarrowAShri16By5(<8 x i16> %x) {
133 ; CHECK-LABEL: NarrowAShri16By5:
135 ; CHECK-NEXT: sqshrn v0.8b, v0.8h, #5
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)
142 define <8 x i8> @NarrowAShrU16By5(<8 x i16> %x) {
143 ; CHECK-LABEL: NarrowAShrU16By5:
145 ; CHECK-NEXT: sshr v0.8h, v0.8h, #5
146 ; CHECK-NEXT: uqxtn v0.8b, v0.8h
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)
153 define <8 x i8> @NarrowAShri16By5ToU8(<8 x i16> %x) {
154 ; CHECK-LABEL: NarrowAShri16By5ToU8:
156 ; CHECK-NEXT: sqshrun v0.8b, v0.8h, #5
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)
163 define <8 x i8> @NarrowLShri16By5(<8 x i16> %x) {
164 ; CHECK-LABEL: NarrowLShri16By5:
166 ; CHECK-NEXT: ushr v0.8h, v0.8h, #5
167 ; CHECK-NEXT: sqxtn v0.8b, v0.8h
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)
174 define <8 x i8> @NarrowLShrU16By5(<8 x i16> %x) {
175 ; CHECK-LABEL: NarrowLShrU16By5:
177 ; CHECK-NEXT: uqshrn v0.8b, v0.8h, #5
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)
184 define <8 x i8> @NarrowLShri16By5ToU8(<8 x i16> %x) {
185 ; CHECK-LABEL: NarrowLShri16By5ToU8:
187 ; CHECK-NEXT: ushr v0.8h, v0.8h, #5
188 ; CHECK-NEXT: sqxtun v0.8b, v0.8h
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)
199 define <4 x i16> @NarrowAShrI32By31(<4 x i32> %x) {
200 ; CHECK-LABEL: NarrowAShrI32By31:
202 ; CHECK-NEXT: sqshrn v0.4h, v0.4s, #16
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)
209 define <4 x i16> @NarrowAShrI32By31ToU16(<4 x i32> %x) {
210 ; CHECK-LABEL: NarrowAShrI32By31ToU16:
212 ; CHECK-NEXT: sqshrun v0.4h, v0.4s, #16
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)
219 define <4 x i16> @NarrowLShrU32By31(<4 x i32> %x) {
220 ; CHECK-LABEL: NarrowLShrU32By31:
222 ; CHECK-NEXT: uqshrn v0.4h, v0.4s, #16
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)
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>