| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc < %s | FileCheck %s |
| |
| ; Make sure that AArch64TargetLowering::ReconstructShuffle does not try to construct |
| ; a NEON tbl if the inputs are wider than a NEON-sized vector. |
| |
| target triple = "aarch64" |
| |
| ; Function Attrs: vscale_range(2,2) |
| define <8 x i16> @deinterleave_4() #0 { |
| ; CHECK-LABEL: deinterleave_4: |
| ; CHECK: // %bb.0: // %iter.check |
| ; CHECK-NEXT: mov x8, xzr |
| ; CHECK-NEXT: mov w9, #32 // =0x20 |
| ; CHECK-NEXT: ldr z0, [x8] |
| ; CHECK-NEXT: mov z1.s, z0.s[4] |
| ; CHECK-NEXT: fmov w8, s1 |
| ; CHECK-NEXT: ldr z1, [x9] |
| ; CHECK-NEXT: mov v0.h[1], w8 |
| ; CHECK-NEXT: fmov w8, s1 |
| ; CHECK-NEXT: mov z1.s, z1.s[4] |
| ; CHECK-NEXT: fmov w9, s1 |
| ; CHECK-NEXT: mov v0.h[2], w8 |
| ; CHECK-NEXT: mov w8, #64 // =0x40 |
| ; CHECK-NEXT: ldr z1, [x8] |
| ; CHECK-NEXT: mov v0.h[3], w9 |
| ; CHECK-NEXT: fmov w8, s1 |
| ; CHECK-NEXT: mov z1.s, z1.s[4] |
| ; CHECK-NEXT: fmov w9, s1 |
| ; CHECK-NEXT: mov v0.h[4], w8 |
| ; CHECK-NEXT: mov w8, #96 // =0x60 |
| ; CHECK-NEXT: ldr z1, [x8] |
| ; CHECK-NEXT: mov v0.h[5], w9 |
| ; CHECK-NEXT: fmov w8, s1 |
| ; CHECK-NEXT: mov z1.s, z1.s[4] |
| ; CHECK-NEXT: mov v0.h[6], w8 |
| ; CHECK-NEXT: fmov w8, s1 |
| ; CHECK-NEXT: mov v0.h[7], w8 |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 |
| ; CHECK-NEXT: ret |
| iter.check: |
| %0 = load <32 x i32>, ptr null, align 8 |
| %1 = shufflevector <32 x i32> %0, <32 x i32> zeroinitializer, <8 x i32> <i32 0, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28> |
| %2 = trunc <8 x i32> %1 to <8 x i16> |
| ret <8 x i16> %2 |
| } |
| |
| ; Function Attrs: vscale_range(2,2) |
| define <8 x i16> @extract_3x_v8i32_loads(ptr %pa, ptr %pb, ptr %pc) #0 { |
| ; CHECK-LABEL: extract_3x_v8i32_loads: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ldr z0, [x0] |
| ; CHECK-NEXT: mov z1.s, z0.s[4] |
| ; CHECK-NEXT: fmov w9, s0 |
| ; CHECK-NEXT: fmov w8, s1 |
| ; CHECK-NEXT: ldr z1, [x1] |
| ; CHECK-NEXT: mov v0.h[1], w8 |
| ; CHECK-NEXT: fmov w10, s1 |
| ; CHECK-NEXT: mov z1.s, z1.s[4] |
| ; CHECK-NEXT: mov v0.h[2], w10 |
| ; CHECK-NEXT: fmov w10, s1 |
| ; CHECK-NEXT: ldr z1, [x2] |
| ; CHECK-NEXT: mov v0.h[3], w10 |
| ; CHECK-NEXT: fmov w10, s1 |
| ; CHECK-NEXT: mov z1.s, z1.s[4] |
| ; CHECK-NEXT: mov v0.h[4], w10 |
| ; CHECK-NEXT: fmov w10, s1 |
| ; CHECK-NEXT: mov v0.h[5], w10 |
| ; CHECK-NEXT: mov v0.h[6], w9 |
| ; CHECK-NEXT: mov v0.h[7], w8 |
| ; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 |
| ; CHECK-NEXT: ret |
| %a = load <8 x i32>, ptr %pa, align 8 |
| %b = load <8 x i32>, ptr %pb, align 8 |
| %c = load <8 x i32>, ptr %pc, align 8 |
| %a0 = extractelement <8 x i32> %a, i64 0 |
| %a4 = extractelement <8 x i32> %a, i64 4 |
| %b0 = extractelement <8 x i32> %b, i64 0 |
| %b4 = extractelement <8 x i32> %b, i64 4 |
| %c0 = extractelement <8 x i32> %c, i64 0 |
| %c4 = extractelement <8 x i32> %c, i64 4 |
| %a0t = trunc i32 %a0 to i16 |
| %a4t = trunc i32 %a4 to i16 |
| %b0t = trunc i32 %b0 to i16 |
| %b4t = trunc i32 %b4 to i16 |
| %c0t = trunc i32 %c0 to i16 |
| %c4t = trunc i32 %c4 to i16 |
| %r0 = insertelement <8 x i16> poison, i16 %a0t, i64 0 |
| %r1 = insertelement <8 x i16> %r0, i16 %a4t, i64 1 |
| %r2 = insertelement <8 x i16> %r1, i16 %b0t, i64 2 |
| %r3 = insertelement <8 x i16> %r2, i16 %b4t, i64 3 |
| %r4 = insertelement <8 x i16> %r3, i16 %c0t, i64 4 |
| %r5 = insertelement <8 x i16> %r4, i16 %c4t, i64 5 |
| %r6 = insertelement <8 x i16> %r5, i16 %a0t, i64 6 |
| %r7 = insertelement <8 x i16> %r6, i16 %a4t, i64 7 |
| ret <8 x i16> %r7 |
| } |
| |
| attributes #0 = { vscale_range(2,2) "target-features"="+neon,+sve" } |