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
7 define void @simple_copy(ptr %dest, ptr %p) {
8 ; CHECK-LABEL: @simple_copy(
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
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
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
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
31 define void @vec_add(ptr %dest, ptr %p) {
32 ; CHECK-LABEL: @vec_add(
34 ; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i16>, ptr [[P:%.*]], align 4
35 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i16> [[TMP0]], <i16 1, i16 1>
36 ; CHECK-NEXT: store <2 x i16> [[TMP1]], ptr [[DEST:%.*]], align 4
37 ; CHECK-NEXT: ret void
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]], <i16 1, i16 1>
43 ; DEFAULT-NEXT: store <2 x i16> [[TMP1]], ptr [[DEST:%.*]], align 4
44 ; DEFAULT-NEXT: ret void
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
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
61 define void @splat_store_i16(ptr %dest, ptr %p) {
62 ; CHECK-LABEL: @splat_store_i16(
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
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
79 %e0 = load i16, ptr %p, align 4
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
87 define void @splat_store_i64(ptr %dest, ptr %p) {
88 ; CHECK-LABEL: @splat_store_i64(
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
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
105 %e0 = load i64, ptr %p, align 4
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
113 define void @splat_store_i64_zero(ptr %dest) {
114 ; CHECK-LABEL: @splat_store_i64_zero(
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
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
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
135 define void @splat_store_i64_one(ptr %dest) {
136 ; CHECK-LABEL: @splat_store_i64_one(
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
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
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
157 define void @splat_store_i32_zero(ptr %dest) {
158 ; CHECK-LABEL: @splat_store_i32_zero(
160 ; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[DEST:%.*]], align 4
161 ; CHECK-NEXT: ret void
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
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
179 define void @splat_store_i32_one(ptr %dest) {
180 ; CHECK-LABEL: @splat_store_i32_one(
182 ; CHECK-NEXT: store <4 x i32> <i32 1, i32 1, i32 1, i32 1>, ptr [[DEST:%.*]], align 4
183 ; CHECK-NEXT: ret void
185 ; DEFAULT-LABEL: @splat_store_i32_one(
186 ; DEFAULT-NEXT: entry:
187 ; DEFAULT-NEXT: store <4 x i32> <i32 1, i32 1, i32 1, i32 1>, ptr [[DEST:%.*]], align 4
188 ; DEFAULT-NEXT: ret void
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
201 define void @store_stepvector_i32(ptr %dest) {
202 ; CHECK-LABEL: @store_stepvector_i32(
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
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
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
235 define void @store_arbitrary_constant_i32(ptr %dest) {
236 ; CHECK-LABEL: @store_arbitrary_constant_i32(
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
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
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