xref: /llvm-project/llvm/test/CodeGen/RISCV/rvv/concat-vectors-constant-stride.ll (revision 1a58e88690c1a48d1082b4ee6b759f5dc49a7144)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+v,+unaligned-vector-mem -target-abi=ilp32 \
3; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV32
4; RUN: llc -mtriple=riscv64 -mattr=+v,+unaligned-vector-mem -target-abi=lp64 \
5; RUN:     -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV64
6
7define void @constant_forward_stride(ptr %s, ptr %d) {
8; CHECK-LABEL: constant_forward_stride:
9; CHECK:       # %bb.0:
10; CHECK-NEXT:    li a2, 16
11; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
12; CHECK-NEXT:    vlse16.v v8, (a0), a2
13; CHECK-NEXT:    vse16.v v8, (a1)
14; CHECK-NEXT:    ret
15  %1 = getelementptr inbounds i8, ptr %s, i64 16
16  %2 = getelementptr inbounds i8, ptr %s, i64 32
17  %3 = getelementptr inbounds i8, ptr %s, i64 48
18  %4 = load <2 x i8>, ptr %s, align 1
19  %5 = load <2 x i8>, ptr %1, align 1
20  %6 = load <2 x i8>, ptr %2, align 1
21  %7 = load <2 x i8>, ptr %3, align 1
22  %8 = shufflevector <2 x i8> %4, <2 x i8> %5, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
23  %9 = shufflevector <2 x i8> %6, <2 x i8> %7, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
24  %10 = shufflevector <4 x i8> %8, <4 x i8> %9, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
25  store <8 x i8> %10, ptr %d, align 1
26  ret void
27}
28
29define void @constant_forward_stride2(ptr %s, ptr %d) {
30; CHECK-LABEL: constant_forward_stride2:
31; CHECK:       # %bb.0:
32; CHECK-NEXT:    addi a0, a0, -48
33; CHECK-NEXT:    li a2, 16
34; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
35; CHECK-NEXT:    vlse16.v v8, (a0), a2
36; CHECK-NEXT:    vse16.v v8, (a1)
37; CHECK-NEXT:    ret
38  %1 = getelementptr inbounds i8, ptr %s, i64 -16
39  %2 = getelementptr inbounds i8, ptr %s, i64 -32
40  %3 = getelementptr inbounds i8, ptr %s, i64 -48
41  %4 = load <2 x i8>, ptr %3, align 1
42  %5 = load <2 x i8>, ptr %2, align 1
43  %6 = load <2 x i8>, ptr %1, align 1
44  %7 = load <2 x i8>, ptr %s, align 1
45  %8 = shufflevector <2 x i8> %4, <2 x i8> %5, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
46  %9 = shufflevector <2 x i8> %6, <2 x i8> %7, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
47  %10 = shufflevector <4 x i8> %8, <4 x i8> %9, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
48  store <8 x i8> %10, ptr %d, align 1
49  ret void
50}
51
52define void @constant_forward_stride3(ptr %s, ptr %d) {
53; CHECK-LABEL: constant_forward_stride3:
54; CHECK:       # %bb.0:
55; CHECK-NEXT:    li a2, 16
56; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
57; CHECK-NEXT:    vlse16.v v8, (a0), a2
58; CHECK-NEXT:    vse16.v v8, (a1)
59; CHECK-NEXT:    ret
60  %1 = getelementptr inbounds i8, ptr %s, i64 16
61  %2 = getelementptr inbounds i8, ptr %s, i64 32
62  %3 = getelementptr inbounds i8, ptr %s, i64 48
63  %4 = getelementptr inbounds i8, ptr %1, i64 0
64  %5 = getelementptr inbounds i8, ptr %2, i64 0
65  %6 = getelementptr inbounds i8, ptr %3, i64 0
66  %7 = load <2 x i8>, ptr %s, align 1
67  %8 = load <2 x i8>, ptr %4, align 1
68  %9 = load <2 x i8>, ptr %5, align 1
69  %10 = load <2 x i8>, ptr %6, align 1
70  %11 = shufflevector <2 x i8> %7, <2 x i8> %8, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
71  %12 = shufflevector <2 x i8> %9, <2 x i8> %10, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
72  %13 = shufflevector <4 x i8> %11, <4 x i8> %12, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
73  store <8 x i8> %13, ptr %d, align 1
74  ret void
75}
76
77define void @constant_back_stride(ptr %s, ptr %d) {
78; CHECK-LABEL: constant_back_stride:
79; CHECK:       # %bb.0:
80; CHECK-NEXT:    li a2, -16
81; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
82; CHECK-NEXT:    vlse16.v v8, (a0), a2
83; CHECK-NEXT:    vse16.v v8, (a1)
84; CHECK-NEXT:    ret
85  %1 = getelementptr inbounds i8, ptr %s, i64 -16
86  %2 = getelementptr inbounds i8, ptr %s, i64 -32
87  %3 = getelementptr inbounds i8, ptr %s, i64 -48
88  %4 = load <2 x i8>, ptr %s, align 1
89  %5 = load <2 x i8>, ptr %1, align 1
90  %6 = load <2 x i8>, ptr %2, align 1
91  %7 = load <2 x i8>, ptr %3, align 1
92  %8 = shufflevector <2 x i8> %4, <2 x i8> %5, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
93  %9 = shufflevector <2 x i8> %6, <2 x i8> %7, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
94  %10 = shufflevector <4 x i8> %8, <4 x i8> %9, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
95  store <8 x i8> %10, ptr %d, align 1
96  ret void
97}
98
99define void @constant_back_stride2(ptr %s, ptr %d) {
100; CHECK-LABEL: constant_back_stride2:
101; CHECK:       # %bb.0:
102; CHECK-NEXT:    addi a0, a0, 48
103; CHECK-NEXT:    li a2, -16
104; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
105; CHECK-NEXT:    vlse16.v v8, (a0), a2
106; CHECK-NEXT:    vse16.v v8, (a1)
107; CHECK-NEXT:    ret
108  %1 = getelementptr inbounds i8, ptr %s, i64 16
109  %2 = getelementptr inbounds i8, ptr %s, i64 32
110  %3 = getelementptr inbounds i8, ptr %s, i64 48
111  %4 = load <2 x i8>, ptr %3, align 1
112  %5 = load <2 x i8>, ptr %2, align 1
113  %6 = load <2 x i8>, ptr %1, align 1
114  %7 = load <2 x i8>, ptr %s, align 1
115  %8 = shufflevector <2 x i8> %4, <2 x i8> %5, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
116  %9 = shufflevector <2 x i8> %6, <2 x i8> %7, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
117  %10 = shufflevector <4 x i8> %8, <4 x i8> %9, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
118  store <8 x i8> %10, ptr %d, align 1
119  ret void
120}
121
122define void @constant_back_stride3(ptr %s, ptr %d) {
123; CHECK-LABEL: constant_back_stride3:
124; CHECK:       # %bb.0:
125; CHECK-NEXT:    li a2, -16
126; CHECK-NEXT:    vsetivli zero, 4, e16, mf2, ta, ma
127; CHECK-NEXT:    vlse16.v v8, (a0), a2
128; CHECK-NEXT:    vse16.v v8, (a1)
129; CHECK-NEXT:    ret
130  %1 = getelementptr inbounds i8, ptr %s, i64 -16
131  %2 = getelementptr inbounds i8, ptr %s, i64 -32
132  %3 = getelementptr inbounds i8, ptr %s, i64 -48
133  %4 = getelementptr inbounds i8, ptr %1, i64 0
134  %5 = getelementptr inbounds i8, ptr %2, i64 0
135  %6 = getelementptr inbounds i8, ptr %3, i64 0
136  %7 = load <2 x i8>, ptr %s, align 1
137  %8 = load <2 x i8>, ptr %4, align 1
138  %9 = load <2 x i8>, ptr %5, align 1
139  %10 = load <2 x i8>, ptr %6, align 1
140  %11 = shufflevector <2 x i8> %7, <2 x i8> %8, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
141  %12 = shufflevector <2 x i8> %9, <2 x i8> %10, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
142  %13 = shufflevector <4 x i8> %11, <4 x i8> %12, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
143  store <8 x i8> %13, ptr %d, align 1
144  ret void
145}
146
147define void @constant_zero_stride(ptr %s, ptr %d) {
148; CHECK-LABEL: constant_zero_stride:
149; CHECK:       # %bb.0:
150; CHECK-NEXT:    vsetivli zero, 2, e8, mf8, ta, ma
151; CHECK-NEXT:    vle8.v v8, (a0)
152; CHECK-NEXT:    vmv1r.v v9, v8
153; CHECK-NEXT:    vsetivli zero, 4, e8, mf4, ta, ma
154; CHECK-NEXT:    vslideup.vi v9, v8, 2
155; CHECK-NEXT:    vse8.v v9, (a1)
156; CHECK-NEXT:    ret
157  %1 = getelementptr inbounds i8, ptr %s, i64 0
158  %2 = load <2 x i8>, ptr %s, align 1
159  %3 = load <2 x i8>, ptr %1, align 1
160  %4 = shufflevector <2 x i8> %2, <2 x i8> %3, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
161  store <4 x i8> %4, ptr %d, align 1
162  ret void
163}
164
165;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
166; RV32: {{.*}}
167; RV64: {{.*}}
168