[SVE][CodeGen] Lower scalable masked gathers
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-masked-gather-legalize.ll
blob962ba079ca9ef15aa6a414fcfd84c67eef95d252
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve < %s | FileCheck %s
4 ; Tests that exercise various type legalisation scenarios for ISD::MGATHER.
6 ; Code generate load of an illegal datatype via promotion.
7 define <vscale x 2 x i32> @masked_gather_nxv2i32(<vscale x 2 x i32*> %ptrs, <vscale x 2 x i1> %mask) {
8 ; CHECK-LABEL: masked_gather_nxv2i32:
9 ; CHECK-DAG: mov x8, xzr
10 ; CHECK-DAG: ld1w { z0.d }, p0/z, [x8, z0.d]
11 ; CHECK:     ret
12   %data = call <vscale x 2 x i32> @llvm.masked.gather.nxv2i32(<vscale x 2 x i32*> %ptrs, i32 4, <vscale x 2 x i1> %mask, <vscale x 2 x i32> undef)
13   ret <vscale x 2 x i32> %data
16 ; Code generate the worst case scenario when all vector types are illegal.
17 define <vscale x 32 x i32> @masked_gather_nxv32i32(i32* %base, <vscale x 32 x i32> %indices, <vscale x 32 x i1> %mask) {
18 ; CHECK-LABEL: masked_gather_nxv32i32:
19 ; CHECK-NOT: unpkhi
20 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z0.s, sxtw #2]
21 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z1.s, sxtw #2]
22 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z2.s, sxtw #2]
23 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z3.s, sxtw #2]
24 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z4.s, sxtw #2]
25 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z5.s, sxtw #2]
26 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z6.s, sxtw #2]
27 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z7.s, sxtw #2]
28 ; CHECK: ret
29   %ptrs = getelementptr i32, i32* %base, <vscale x 32 x i32> %indices
30   %data = call <vscale x 32 x i32> @llvm.masked.gather.nxv32i32(<vscale x 32 x i32*> %ptrs, i32 4, <vscale x 32 x i1> %mask, <vscale x 32 x i32> undef)
31   ret <vscale x 32 x i32> %data
34 ; TODO: Currently, the sign extend gets applied to the values after a 'uzp1' of two
35 ; registers, so it doesn't get folded away. Same for any other vector-of-pointers
36 ; style gathers which don't fit in an <vscale x 2 x type*> single register. Better folding
37 ; is required before we can check those off.
38 define <vscale x 4 x i32> @masked_sgather_nxv4i8(<vscale x 4 x i8*> %ptrs, <vscale x 4 x i1> %mask) {
39 ; CHECK-LABEL: masked_sgather_nxv4i8:
40 ; CHECK:         pfalse p1.b
41 ; CHECK-NEXT:    mov x8, xzr
42 ; CHECK-NEXT:    zip2 p2.s, p0.s, p1.s
43 ; CHECK-NEXT:    zip1 p0.s, p0.s, p1.s
44 ; CHECK-NEXT:    ld1b { z1.d }, p2/z, [x8, z1.d]
45 ; CHECK-NEXT:    ld1b { z0.d }, p0/z, [x8, z0.d]
46 ; CHECK-NEXT:    ptrue p0.s
47 ; CHECK-NEXT:    uzp1 z0.s, z0.s, z1.s
48 ; CHECK-NEXT:    sxtb z0.s, p0/m, z0.s
49 ; CHECK-NEXT:    ret
50   %vals = call <vscale x 4 x i8> @llvm.masked.gather.nxv4i8(<vscale x 4 x i8*> %ptrs, i32 1, <vscale x 4 x i1> %mask, <vscale x 4 x i8> undef)
51   %svals = sext <vscale x 4 x i8> %vals to <vscale x 4 x i32>
52   ret <vscale x 4 x i32> %svals
55 declare <vscale x 2 x i8> @llvm.masked.gather.nxv2i8(<vscale x 2 x i8*>, i32, <vscale x 2 x i1>, <vscale x 2 x i8>)
56 declare <vscale x 2 x i16> @llvm.masked.gather.nxv2i16(<vscale x 2 x i16*>, i32, <vscale x 2 x i1>, <vscale x 2 x i16>)
57 declare <vscale x 2 x i32> @llvm.masked.gather.nxv2i32(<vscale x 2 x i32*>, i32, <vscale x 2 x i1>, <vscale x 2 x i32>)
59 declare <vscale x 4 x i8> @llvm.masked.gather.nxv4i8(<vscale x 4 x i8*>, i32, <vscale x 4 x i1>, <vscale x 4 x i8>)
61 declare <vscale x 16 x i8> @llvm.masked.gather.nxv16i8(<vscale x 16 x i8*>, i32, <vscale x 16 x i1>, <vscale x 16 x i8>)
62 declare <vscale x 32 x i32> @llvm.masked.gather.nxv32i32(<vscale x 32 x i32*>, i32, <vscale x 32 x i1>, <vscale x 32 x i32>)