[SVE][CodeGen] Extend index of masked gathers
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-masked-gather-legalize.ll
blob4482730a7d74c0a00ec2b8841e676a545fcb1c84
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve -aarch64-enable-mgather-combine=0 < %s | FileCheck %s
3 ; RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve -aarch64-enable-mgather-combine=1 < %s | FileCheck %s
5 ; Test for multiple uses of the mgather where the s/zext should not be combined
7 define <vscale x 2 x i64> @masked_sgather_sext(i8* %base, <vscale x 2 x i64> %offsets, <vscale x 2 x i1> %mask, <vscale x 2 x i8> %vals) {
8 ; CHECK-LABEL: masked_sgather_sext:
9 ; CHECK:       // %bb.0:
10 ; CHECK-NEXT:    ld1sb { z0.d }, p0/z, [x0, z0.d]
11 ; CHECK-NEXT:    ptrue p0.d
12 ; CHECK-NEXT:    sxtb z2.d, p0/m, z0.d
13 ; CHECK-NEXT:    add z0.d, z0.d, z1.d
14 ; CHECK-NEXT:    sxtb z0.d, p0/m, z0.d
15 ; CHECK-NEXT:    mul z0.d, p0/m, z0.d, z2.d
16 ; CHECK-NEXT:    ret
17   %ptrs = getelementptr i8, i8* %base, <vscale x 2 x i64> %offsets
18   %data = call <vscale x 2 x i8> @llvm.masked.gather.nxv2i8(<vscale x 2 x i8*> %ptrs, i32 1, <vscale x 2 x i1> %mask, <vscale x 2 x i8> undef)
19   %data.sext = sext <vscale x 2 x i8> %data to <vscale x 2 x i64>
20   %add = add <vscale x 2 x i8> %data, %vals
21   %add.sext = sext <vscale x 2 x i8> %add to <vscale x 2 x i64>
22   %mul = mul <vscale x 2 x i64> %data.sext, %add.sext
23   ret <vscale x 2 x i64> %mul
26 define <vscale x 2 x i64> @masked_sgather_zext(i8* %base, <vscale x 2 x i64> %offsets, <vscale x 2 x i1> %mask, <vscale x 2 x i8> %vals) {
27 ; CHECK-LABEL: masked_sgather_zext:
28 ; CHECK:       // %bb.0:
29 ; CHECK-NEXT: ld1sb { z0.d }, p0/z, [x0, z0.d]
30 ; CHECK-NEXT: ptrue p0.d
31 ; CHECK-NEXT: add z1.d, z0.d, z1.d
32 ; CHECK-NEXT: and z0.d, z0.d, #0xff
33 ; CHECK-NEXT: and z1.d, z1.d, #0xff
34 ; CHECK-NEXT: mul z0.d, p0/m, z0.d, z1.d
35 ; CHECK-NEXT: ret
36   %ptrs = getelementptr i8, i8* %base, <vscale x 2 x i64> %offsets
37   %data = call <vscale x 2 x i8> @llvm.masked.gather.nxv2i8(<vscale x 2 x i8*> %ptrs, i32 1, <vscale x 2 x i1> %mask, <vscale x 2 x i8> undef)
38   %data.zext = zext <vscale x 2 x i8> %data to <vscale x 2 x i64>
39   %add = add <vscale x 2 x i8> %data, %vals
40   %add.zext = zext <vscale x 2 x i8> %add to <vscale x 2 x i64>
41   %mul = mul <vscale x 2 x i64> %data.zext, %add.zext
42   ret <vscale x 2 x i64> %mul
45 ; Tests that exercise various type legalisation scenarios for ISD::MGATHER.
47 ; Code generate load of an illegal datatype via promotion.
48 define <vscale x 2 x i32> @masked_gather_nxv2i32(<vscale x 2 x i32*> %ptrs, <vscale x 2 x i1> %mask) {
49 ; CHECK-LABEL: masked_gather_nxv2i32:
50 ; CHECK-DAG: mov x8, xzr
51 ; CHECK-DAG: ld1sw { z0.d }, p0/z, [x8, z0.d]
52 ; CHECK:     ret
53   %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)
54   ret <vscale x 2 x i32> %data
57 ; Code generate the worst case scenario when all vector types are legal.
58 define <vscale x 16 x i8> @masked_gather_nxv16i8(i8* %base, <vscale x 16 x i8> %indices, <vscale x 16 x i1> %mask) {
59 ; CHECK-LABEL: masked_gather_nxv16i8:
60 ; CHECK-DAG: ld1sb { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, {{z[0-9]+}}.s, sxtw]
61 ; CHECK-DAG: ld1sb { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, {{z[0-9]+}}.s, sxtw]
62 ; CHECK-DAG: ld1sb { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, {{z[0-9]+}}.s, sxtw]
63 ; CHECK-DAG: ld1sb { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, {{z[0-9]+}}.s, sxtw]
64 ; CHECK: ret
65   %ptrs = getelementptr i8, i8* %base, <vscale x 16 x i8> %indices
66   %data = call <vscale x 16 x i8> @llvm.masked.gather.nxv16i8(<vscale x 16 x i8*> %ptrs, i32 1, <vscale x 16 x i1> %mask, <vscale x 16 x i8> undef)
67   ret <vscale x 16 x i8> %data
70 ; Code generate the worst case scenario when all vector types are illegal.
71 define <vscale x 32 x i32> @masked_gather_nxv32i32(i32* %base, <vscale x 32 x i32> %indices, <vscale x 32 x i1> %mask) {
72 ; CHECK-LABEL: masked_gather_nxv32i32:
73 ; CHECK-NOT: unpkhi
74 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z0.s, sxtw #2]
75 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z1.s, sxtw #2]
76 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z2.s, sxtw #2]
77 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z3.s, sxtw #2]
78 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z4.s, sxtw #2]
79 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z5.s, sxtw #2]
80 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z6.s, sxtw #2]
81 ; CHECK-DAG: ld1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/z, [x0, z7.s, sxtw #2]
82 ; CHECK: ret
83   %ptrs = getelementptr i32, i32* %base, <vscale x 32 x i32> %indices
84   %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)
85   ret <vscale x 32 x i32> %data
88 ; TODO: Currently, the sign extend gets applied to the values after a 'uzp1' of two
89 ; registers, so it doesn't get folded away. Same for any other vector-of-pointers
90 ; style gathers which don't fit in an <vscale x 2 x type*> single register. Better folding
91 ; is required before we can check those off.
92 define <vscale x 4 x i32> @masked_sgather_nxv4i8(<vscale x 4 x i8*> %ptrs, <vscale x 4 x i1> %mask) {
93 ; CHECK-LABEL: masked_sgather_nxv4i8:
94 ; CHECK:         pfalse p1.b
95 ; CHECK-NEXT:    mov x8, xzr
96 ; CHECK-NEXT:    zip2 p2.s, p0.s, p1.s
97 ; CHECK-NEXT:    zip1 p0.s, p0.s, p1.s
98 ; CHECK-NEXT:    ld1sb { z1.d }, p2/z, [x8, z1.d]
99 ; CHECK-NEXT:    ld1sb { z0.d }, p0/z, [x8, z0.d]
100 ; CHECK-NEXT:    ptrue p0.s
101 ; CHECK-NEXT:    uzp1 z0.s, z0.s, z1.s
102 ; CHECK-NEXT:    sxtb z0.s, p0/m, z0.s
103 ; CHECK-NEXT:    ret
104   %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)
105   %svals = sext <vscale x 4 x i8> %vals to <vscale x 4 x i32>
106   ret <vscale x 4 x i32> %svals
109 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>)
110 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>)
111 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>)
113 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>)
115 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>)
116 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>)