xref: /llvm-project/llvm/test/Transforms/SLPVectorizer/RISCV/load-store.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=slp-vectorizer -mtriple=riscv64 -mattr=+v \
3; RUN: -riscv-v-vector-bits-min=-1 -riscv-v-slp-max-vf=0 -S | FileCheck %s --check-prefixes=CHECK
4; RUN: opt < %s -passes=slp-vectorizer -mtriple=riscv64 -mattr=+v -S | FileCheck %s --check-prefixes=DEFAULT
5
6
7define void @simple_copy(ptr %dest, ptr %p) {
8; CHECK-LABEL: @simple_copy(
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x i16>, ptr [[P:%.*]], align 4
11; CHECK-NEXT:    store <2 x i16> [[TMP0]], ptr [[DEST:%.*]], align 4
12; CHECK-NEXT:    ret void
13;
14; DEFAULT-LABEL: @simple_copy(
15; DEFAULT-NEXT:  entry:
16; DEFAULT-NEXT:    [[TMP0:%.*]] = load <2 x i16>, ptr [[P:%.*]], align 4
17; DEFAULT-NEXT:    store <2 x i16> [[TMP0]], ptr [[DEST:%.*]], align 4
18; DEFAULT-NEXT:    ret void
19;
20entry:
21  %e0 = load i16, ptr %p, align 4
22  %inc = getelementptr inbounds i16, ptr %p, i64 1
23  %e1 = load i16, ptr %inc, align 2
24
25  store i16 %e0, ptr %dest, align 4
26  %inc2 = getelementptr inbounds i16, ptr %dest, i64 1
27  store i16 %e1, ptr %inc2, align 2
28  ret void
29}
30
31define void @vec_add(ptr %dest, ptr %p) {
32; CHECK-LABEL: @vec_add(
33; CHECK-NEXT:  entry:
34; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x i16>, ptr [[P:%.*]], align 4
35; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i16> [[TMP0]], splat (i16 1)
36; CHECK-NEXT:    store <2 x i16> [[TMP1]], ptr [[DEST:%.*]], align 4
37; CHECK-NEXT:    ret void
38;
39; DEFAULT-LABEL: @vec_add(
40; DEFAULT-NEXT:  entry:
41; DEFAULT-NEXT:    [[TMP0:%.*]] = load <2 x i16>, ptr [[P:%.*]], align 4
42; DEFAULT-NEXT:    [[TMP1:%.*]] = add <2 x i16> [[TMP0]], splat (i16 1)
43; DEFAULT-NEXT:    store <2 x i16> [[TMP1]], ptr [[DEST:%.*]], align 4
44; DEFAULT-NEXT:    ret void
45;
46entry:
47  %e0 = load i16, ptr %p, align 4
48  %inc = getelementptr inbounds i16, ptr %p, i64 1
49  %e1 = load i16, ptr %inc, align 2
50
51  %a0 = add i16 %e0, 1
52  %a1 = add i16 %e1, 1
53
54  store i16 %a0, ptr %dest, align 4
55  %inc2 = getelementptr inbounds i16, ptr %dest, i64 1
56  store i16 %a1, ptr %inc2, align 2
57  ret void
58}
59
60
61define void @splat_store_i16(ptr %dest, ptr %p) {
62; CHECK-LABEL: @splat_store_i16(
63; CHECK-NEXT:  entry:
64; CHECK-NEXT:    [[E0:%.*]] = load i16, ptr [[P:%.*]], align 4
65; CHECK-NEXT:    store i16 [[E0]], ptr [[DEST:%.*]], align 4
66; CHECK-NEXT:    [[INC2:%.*]] = getelementptr inbounds i16, ptr [[DEST]], i64 1
67; CHECK-NEXT:    store i16 [[E0]], ptr [[INC2]], align 2
68; CHECK-NEXT:    ret void
69;
70; DEFAULT-LABEL: @splat_store_i16(
71; DEFAULT-NEXT:  entry:
72; DEFAULT-NEXT:    [[E0:%.*]] = load i16, ptr [[P:%.*]], align 4
73; DEFAULT-NEXT:    store i16 [[E0]], ptr [[DEST:%.*]], align 4
74; DEFAULT-NEXT:    [[INC2:%.*]] = getelementptr inbounds i16, ptr [[DEST]], i64 1
75; DEFAULT-NEXT:    store i16 [[E0]], ptr [[INC2]], align 2
76; DEFAULT-NEXT:    ret void
77;
78entry:
79  %e0 = load i16, ptr %p, align 4
80
81  store i16 %e0, ptr %dest, align 4
82  %inc2 = getelementptr inbounds i16, ptr %dest, i64 1
83  store i16 %e0, ptr %inc2, align 2
84  ret void
85}
86
87define void @splat_store_i64(ptr %dest, ptr %p) {
88; CHECK-LABEL: @splat_store_i64(
89; CHECK-NEXT:  entry:
90; CHECK-NEXT:    [[E0:%.*]] = load i64, ptr [[P:%.*]], align 4
91; CHECK-NEXT:    store i64 [[E0]], ptr [[DEST:%.*]], align 4
92; CHECK-NEXT:    [[INC2:%.*]] = getelementptr inbounds i64, ptr [[DEST]], i64 1
93; CHECK-NEXT:    store i64 [[E0]], ptr [[INC2]], align 2
94; CHECK-NEXT:    ret void
95;
96; DEFAULT-LABEL: @splat_store_i64(
97; DEFAULT-NEXT:  entry:
98; DEFAULT-NEXT:    [[E0:%.*]] = load i64, ptr [[P:%.*]], align 4
99; DEFAULT-NEXT:    store i64 [[E0]], ptr [[DEST:%.*]], align 4
100; DEFAULT-NEXT:    [[INC2:%.*]] = getelementptr inbounds i64, ptr [[DEST]], i64 1
101; DEFAULT-NEXT:    store i64 [[E0]], ptr [[INC2]], align 2
102; DEFAULT-NEXT:    ret void
103;
104entry:
105  %e0 = load i64, ptr %p, align 4
106
107  store i64 %e0, ptr %dest, align 4
108  %inc2 = getelementptr inbounds i64, ptr %dest, i64 1
109  store i64 %e0, ptr %inc2, align 2
110  ret void
111}
112
113define void @splat_store_i64_zero(ptr %dest) {
114; CHECK-LABEL: @splat_store_i64_zero(
115; CHECK-NEXT:  entry:
116; CHECK-NEXT:    store i64 0, ptr [[DEST:%.*]], align 4
117; CHECK-NEXT:    [[INC2:%.*]] = getelementptr inbounds i64, ptr [[DEST]], i64 1
118; CHECK-NEXT:    store i64 0, ptr [[INC2]], align 2
119; CHECK-NEXT:    ret void
120;
121; DEFAULT-LABEL: @splat_store_i64_zero(
122; DEFAULT-NEXT:  entry:
123; DEFAULT-NEXT:    store i64 0, ptr [[DEST:%.*]], align 4
124; DEFAULT-NEXT:    [[INC2:%.*]] = getelementptr inbounds i64, ptr [[DEST]], i64 1
125; DEFAULT-NEXT:    store i64 0, ptr [[INC2]], align 2
126; DEFAULT-NEXT:    ret void
127;
128entry:
129  store i64 0, ptr %dest, align 4
130  %inc2 = getelementptr inbounds i64, ptr %dest, i64 1
131  store i64 0, ptr %inc2, align 2
132  ret void
133}
134
135define void @splat_store_i64_one(ptr %dest) {
136; CHECK-LABEL: @splat_store_i64_one(
137; CHECK-NEXT:  entry:
138; CHECK-NEXT:    store i64 1, ptr [[DEST:%.*]], align 4
139; CHECK-NEXT:    [[INC2:%.*]] = getelementptr inbounds i64, ptr [[DEST]], i64 1
140; CHECK-NEXT:    store i64 1, ptr [[INC2]], align 2
141; CHECK-NEXT:    ret void
142;
143; DEFAULT-LABEL: @splat_store_i64_one(
144; DEFAULT-NEXT:  entry:
145; DEFAULT-NEXT:    store i64 1, ptr [[DEST:%.*]], align 4
146; DEFAULT-NEXT:    [[INC2:%.*]] = getelementptr inbounds i64, ptr [[DEST]], i64 1
147; DEFAULT-NEXT:    store i64 1, ptr [[INC2]], align 2
148; DEFAULT-NEXT:    ret void
149;
150entry:
151  store i64 1, ptr %dest, align 4
152  %inc2 = getelementptr inbounds i64, ptr %dest, i64 1
153  store i64 1, ptr %inc2, align 2
154  ret void
155}
156
157define void @splat_store_i32_zero(ptr %dest) {
158; CHECK-LABEL: @splat_store_i32_zero(
159; CHECK-NEXT:  entry:
160; CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr [[DEST:%.*]], align 4
161; CHECK-NEXT:    ret void
162;
163; DEFAULT-LABEL: @splat_store_i32_zero(
164; DEFAULT-NEXT:  entry:
165; DEFAULT-NEXT:    store <4 x i32> zeroinitializer, ptr [[DEST:%.*]], align 4
166; DEFAULT-NEXT:    ret void
167;
168entry:
169  store i32 0, ptr %dest, align 4
170  %inc1 = getelementptr inbounds i32, ptr %dest, i64 1
171  store i32 0, ptr %inc1, align 2
172  %inc2 = getelementptr inbounds i32, ptr %dest, i64 2
173  store i32 0, ptr %inc2, align 2
174  %inc3 = getelementptr inbounds i32, ptr %dest, i64 3
175  store i32 0, ptr %inc3, align 2
176  ret void
177}
178
179define void @splat_store_i32_one(ptr %dest) {
180; CHECK-LABEL: @splat_store_i32_one(
181; CHECK-NEXT:  entry:
182; CHECK-NEXT:    store <4 x i32> splat (i32 1), ptr [[DEST:%.*]], align 4
183; CHECK-NEXT:    ret void
184;
185; DEFAULT-LABEL: @splat_store_i32_one(
186; DEFAULT-NEXT:  entry:
187; DEFAULT-NEXT:    store <4 x i32> splat (i32 1), ptr [[DEST:%.*]], align 4
188; DEFAULT-NEXT:    ret void
189;
190entry:
191  store i32 1, ptr %dest, align 4
192  %inc1 = getelementptr inbounds i32, ptr %dest, i64 1
193  store i32 1, ptr %inc1, align 2
194  %inc2 = getelementptr inbounds i32, ptr %dest, i64 2
195  store i32 1, ptr %inc2, align 2
196  %inc3 = getelementptr inbounds i32, ptr %dest, i64 3
197  store i32 1, ptr %inc3, align 2
198  ret void
199}
200
201define void @store_stepvector_i32(ptr %dest) {
202; CHECK-LABEL: @store_stepvector_i32(
203; CHECK-NEXT:  entry:
204; CHECK-NEXT:    store i32 0, ptr [[DEST:%.*]], align 4
205; CHECK-NEXT:    [[INC1:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 1
206; CHECK-NEXT:    store i32 1, ptr [[INC1]], align 2
207; CHECK-NEXT:    [[INC2:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 2
208; CHECK-NEXT:    store i32 2, ptr [[INC2]], align 2
209; CHECK-NEXT:    [[INC3:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 3
210; CHECK-NEXT:    store i32 3, ptr [[INC3]], align 2
211; CHECK-NEXT:    ret void
212;
213; DEFAULT-LABEL: @store_stepvector_i32(
214; DEFAULT-NEXT:  entry:
215; DEFAULT-NEXT:    store i32 0, ptr [[DEST:%.*]], align 4
216; DEFAULT-NEXT:    [[INC1:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 1
217; DEFAULT-NEXT:    store i32 1, ptr [[INC1]], align 2
218; DEFAULT-NEXT:    [[INC2:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 2
219; DEFAULT-NEXT:    store i32 2, ptr [[INC2]], align 2
220; DEFAULT-NEXT:    [[INC3:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 3
221; DEFAULT-NEXT:    store i32 3, ptr [[INC3]], align 2
222; DEFAULT-NEXT:    ret void
223;
224entry:
225  store i32 0, ptr %dest, align 4
226  %inc1 = getelementptr inbounds i32, ptr %dest, i64 1
227  store i32 1, ptr %inc1, align 2
228  %inc2 = getelementptr inbounds i32, ptr %dest, i64 2
229  store i32 2, ptr %inc2, align 2
230  %inc3 = getelementptr inbounds i32, ptr %dest, i64 3
231  store i32 3, ptr %inc3, align 2
232  ret void
233}
234
235define void @store_arbitrary_constant_i32(ptr %dest) {
236; CHECK-LABEL: @store_arbitrary_constant_i32(
237; CHECK-NEXT:  entry:
238; CHECK-NEXT:    store i32 0, ptr [[DEST:%.*]], align 4
239; CHECK-NEXT:    [[INC1:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 1
240; CHECK-NEXT:    store i32 -33, ptr [[INC1]], align 2
241; CHECK-NEXT:    [[INC2:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 2
242; CHECK-NEXT:    store i32 44, ptr [[INC2]], align 2
243; CHECK-NEXT:    [[INC3:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 3
244; CHECK-NEXT:    store i32 77, ptr [[INC3]], align 2
245; CHECK-NEXT:    ret void
246;
247; DEFAULT-LABEL: @store_arbitrary_constant_i32(
248; DEFAULT-NEXT:  entry:
249; DEFAULT-NEXT:    store i32 0, ptr [[DEST:%.*]], align 4
250; DEFAULT-NEXT:    [[INC1:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 1
251; DEFAULT-NEXT:    store i32 -33, ptr [[INC1]], align 2
252; DEFAULT-NEXT:    [[INC2:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 2
253; DEFAULT-NEXT:    store i32 44, ptr [[INC2]], align 2
254; DEFAULT-NEXT:    [[INC3:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 3
255; DEFAULT-NEXT:    store i32 77, ptr [[INC3]], align 2
256; DEFAULT-NEXT:    ret void
257;
258entry:
259  store i32 0, ptr %dest, align 4
260  %inc1 = getelementptr inbounds i32, ptr %dest, i64 1
261  store i32 -33, ptr %inc1, align 2
262  %inc2 = getelementptr inbounds i32, ptr %dest, i64 2
263  store i32 44, ptr %inc2, align 2
264  %inc3 = getelementptr inbounds i32, ptr %dest, i64 3
265  store i32 77, ptr %inc3, align 2
266  ret void
267}
268