1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2 ; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=riscv32 -mattr=+m,+v | FileCheck %s
3 ; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=riscv64 -mattr=+m,+v | FileCheck %s
4 ; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=riscv32 -mattr=+v,+experimental-zvbb | FileCheck %s
5 ; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=riscv64 -mattr=+v,+experimental-zvbb | FileCheck %s
7 define <4 x float> @rint_v4f32(ptr %a) {
8 ; CHECK-LABEL: define <4 x float> @rint_v4f32(
9 ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
11 ; CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[A]], align 16
12 ; CHECK-NEXT: [[TMP1:%.*]] = call <4 x float> @llvm.rint.v4f32(<4 x float> [[TMP0]])
13 ; CHECK-NEXT: ret <4 x float> [[TMP1]]
16 %0 = load <4 x float>, ptr %a
17 %vecext = extractelement <4 x float> %0, i64 0
18 %1 = call float @llvm.rint.f32(float %vecext)
19 %vecins = insertelement <4 x float> undef, float %1, i64 0
20 %vecext.1 = extractelement <4 x float> %0, i64 1
21 %2 = call float @llvm.rint.f32(float %vecext.1)
22 %vecins.1 = insertelement <4 x float> %vecins, float %2, i64 1
23 %vecext.2 = extractelement <4 x float> %0, i64 2
24 %3 = call float @llvm.rint.f32(float %vecext.2)
25 %vecins.2 = insertelement <4 x float> %vecins.1, float %3, i64 2
26 %vecext.3 = extractelement <4 x float> %0, i64 3
27 %4 = call float @llvm.rint.f32(float %vecext.3)
28 %vecins.3 = insertelement <4 x float> %vecins.2, float %4, i64 3
29 ret <4 x float> %vecins.3
32 define <2 x i32> @lrint_v2i32f32(ptr %a) {
33 ; CHECK-LABEL: define <2 x i32> @lrint_v2i32f32(
34 ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] {
36 ; CHECK-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[A]], align 8
37 ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.lrint.v2i32.v2f32(<2 x float> [[TMP0]])
38 ; CHECK-NEXT: ret <2 x i32> [[TMP1]]
41 %0 = load <2 x float>, ptr %a
42 %vecext = extractelement <2 x float> %0, i32 0
43 %1 = call i32 @llvm.lrint.i32.f32(float %vecext)
44 %vecins = insertelement <2 x i32> undef, i32 %1, i32 0
45 %vecext.1 = extractelement <2 x float> %0, i32 1
46 %2 = call i32 @llvm.lrint.i32.f32(float %vecext.1)
47 %vecins.1 = insertelement <2 x i32> %vecins, i32 %2, i32 1
48 ret <2 x i32> %vecins.1
51 define <4 x i32> @lrint_v4i32f32(ptr %a) {
52 ; CHECK-LABEL: define <4 x i32> @lrint_v4i32f32(
53 ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] {
55 ; CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[A]], align 16
56 ; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.lrint.v4i32.v4f32(<4 x float> [[TMP0]])
57 ; CHECK-NEXT: ret <4 x i32> [[TMP1]]
60 %0 = load <4 x float>, ptr %a
61 %vecext = extractelement <4 x float> %0, i32 0
62 %1 = call i32 @llvm.lrint.i32.f32(float %vecext)
63 %vecins = insertelement <4 x i32> undef, i32 %1, i32 0
64 %vecext.1 = extractelement <4 x float> %0, i32 1
65 %2 = call i32 @llvm.lrint.i32.f32(float %vecext.1)
66 %vecins.1 = insertelement <4 x i32> %vecins, i32 %2, i32 1
67 %vecext.2 = extractelement <4 x float> %0, i32 2
68 %3 = call i32 @llvm.lrint.i32.f32(float %vecext.2)
69 %vecins.2 = insertelement <4 x i32> %vecins.1, i32 %3, i32 2
70 %vecext.3 = extractelement <4 x float> %0, i32 3
71 %4 = call i32 @llvm.lrint.i32.f32(float %vecext.3)
72 %vecins.3 = insertelement <4 x i32> %vecins.2, i32 %4, i32 3
73 ret <4 x i32> %vecins.3
76 define <8 x i32> @lrint_v8i32f32(ptr %a) {
77 ; CHECK-LABEL: define <8 x i32> @lrint_v8i32f32(
78 ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] {
80 ; CHECK-NEXT: [[TMP0:%.*]] = load <8 x float>, ptr [[A]], align 32
81 ; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i32> @llvm.lrint.v8i32.v8f32(<8 x float> [[TMP0]])
82 ; CHECK-NEXT: ret <8 x i32> [[TMP1]]
85 %0 = load <8 x float>, ptr %a
86 %vecext = extractelement <8 x float> %0, i32 0
87 %1 = call i32 @llvm.lrint.i32.f32(float %vecext)
88 %vecins = insertelement <8 x i32> undef, i32 %1, i32 0
89 %vecext.1 = extractelement <8 x float> %0, i32 1
90 %2 = call i32 @llvm.lrint.i32.f32(float %vecext.1)
91 %vecins.1 = insertelement <8 x i32> %vecins, i32 %2, i32 1
92 %vecext.2 = extractelement <8 x float> %0, i32 2
93 %3 = call i32 @llvm.lrint.i32.f32(float %vecext.2)
94 %vecins.2 = insertelement <8 x i32> %vecins.1, i32 %3, i32 2
95 %vecext.3 = extractelement <8 x float> %0, i32 3
96 %4 = call i32 @llvm.lrint.i32.f32(float %vecext.3)
97 %vecins.3 = insertelement <8 x i32> %vecins.2, i32 %4, i32 3
98 %vecext.4 = extractelement <8 x float> %0, i32 4
99 %5 = call i32 @llvm.lrint.i32.f32(float %vecext.4)
100 %vecins.4 = insertelement <8 x i32> %vecins.3, i32 %5, i32 4
101 %vecext.5 = extractelement <8 x float> %0, i32 5
102 %6 = call i32 @llvm.lrint.i32.f32(float %vecext.5)
103 %vecins.5 = insertelement <8 x i32> %vecins.4, i32 %6, i32 5
104 %vecext.6 = extractelement <8 x float> %0, i32 6
105 %7 = call i32 @llvm.lrint.i32.f32(float %vecext.6)
106 %vecins.6 = insertelement <8 x i32> %vecins.5, i32 %7, i32 6
107 %vecext.7 = extractelement <8 x float> %0, i32 7
108 %8 = call i32 @llvm.lrint.i32.f32(float %vecext.7)
109 %vecins.7 = insertelement <8 x i32> %vecins.6, i32 %8, i32 7
110 ret <8 x i32> %vecins.7
113 define <2 x i64> @lrint_v2i64f32(ptr %a) {
114 ; CHECK-LABEL: define <2 x i64> @lrint_v2i64f32(
115 ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] {
117 ; CHECK-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[A]], align 8
118 ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i64> @llvm.lrint.v2i64.v2f32(<2 x float> [[TMP0]])
119 ; CHECK-NEXT: ret <2 x i64> [[TMP1]]
122 %0 = load <2 x float>, ptr %a
123 %vecext = extractelement <2 x float> %0, i64 0
124 %1 = call i64 @llvm.lrint.i64.f32(float %vecext)
125 %vecins = insertelement <2 x i64> undef, i64 %1, i64 0
126 %vecext.1 = extractelement <2 x float> %0, i64 1
127 %2 = call i64 @llvm.lrint.i64.f32(float %vecext.1)
128 %vecins.1 = insertelement <2 x i64> %vecins, i64 %2, i64 1
129 ret <2 x i64> %vecins.1
132 define <4 x i64> @lrint_v4i64f32(ptr %a) {
133 ; CHECK-LABEL: define <4 x i64> @lrint_v4i64f32(
134 ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] {
136 ; CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[A]], align 16
137 ; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i64> @llvm.lrint.v4i64.v4f32(<4 x float> [[TMP0]])
138 ; CHECK-NEXT: ret <4 x i64> [[TMP1]]
141 %0 = load <4 x float>, ptr %a
142 %vecext = extractelement <4 x float> %0, i64 0
143 %1 = call i64 @llvm.lrint.i64.f32(float %vecext)
144 %vecins = insertelement <4 x i64> undef, i64 %1, i64 0
145 %vecext.1 = extractelement <4 x float> %0, i64 1
146 %2 = call i64 @llvm.lrint.i64.f32(float %vecext.1)
147 %vecins.1 = insertelement <4 x i64> %vecins, i64 %2, i64 1
148 %vecext.2 = extractelement <4 x float> %0, i64 2
149 %3 = call i64 @llvm.lrint.i64.f32(float %vecext.2)
150 %vecins.2 = insertelement <4 x i64> %vecins.1, i64 %3, i64 2
151 %vecext.3 = extractelement <4 x float> %0, i64 3
152 %4 = call i64 @llvm.lrint.i64.f32(float %vecext.3)
153 %vecins.3 = insertelement <4 x i64> %vecins.2, i64 %4, i64 3
154 ret <4 x i64> %vecins.3
157 define <8 x i64> @lrint_v8i64f32(ptr %a) {
158 ; CHECK-LABEL: define <8 x i64> @lrint_v8i64f32(
159 ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] {
161 ; CHECK-NEXT: [[TMP0:%.*]] = load <8 x float>, ptr [[A]], align 32
162 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x float> [[TMP0]], <8 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
163 ; CHECK-NEXT: [[TMP2:%.*]] = call <4 x i64> @llvm.lrint.v4i64.v4f32(<4 x float> [[TMP1]])
164 ; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i64> [[TMP2]], <4 x i64> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
165 ; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <8 x float> [[TMP0]], <8 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
166 ; CHECK-NEXT: [[TMP5:%.*]] = call <4 x i64> @llvm.lrint.v4i64.v4f32(<4 x float> [[TMP4]])
167 ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <4 x i64> [[TMP5]], <4 x i64> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
168 ; CHECK-NEXT: [[VECINS_71:%.*]] = shufflevector <8 x i64> [[TMP3]], <8 x i64> [[TMP6]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
169 ; CHECK-NEXT: ret <8 x i64> [[VECINS_71]]
172 %0 = load <8 x float>, ptr %a
173 %vecext = extractelement <8 x float> %0, i64 0
174 %1 = call i64 @llvm.lrint.i64.f32(float %vecext)
175 %vecins = insertelement <8 x i64> undef, i64 %1, i64 0
176 %vecext.1 = extractelement <8 x float> %0, i64 1
177 %2 = call i64 @llvm.lrint.i64.f32(float %vecext.1)
178 %vecins.1 = insertelement <8 x i64> %vecins, i64 %2, i64 1
179 %vecext.2 = extractelement <8 x float> %0, i64 2
180 %3 = call i64 @llvm.lrint.i64.f32(float %vecext.2)
181 %vecins.2 = insertelement <8 x i64> %vecins.1, i64 %3, i64 2
182 %vecext.3 = extractelement <8 x float> %0, i64 3
183 %4 = call i64 @llvm.lrint.i64.f32(float %vecext.3)
184 %vecins.3 = insertelement <8 x i64> %vecins.2, i64 %4, i64 3
185 %vecext.4 = extractelement <8 x float> %0, i64 4
186 %5 = call i64 @llvm.lrint.i64.f32(float %vecext.4)
187 %vecins.4 = insertelement <8 x i64> %vecins.3, i64 %5, i64 4
188 %vecext.5 = extractelement <8 x float> %0, i64 5
189 %6 = call i64 @llvm.lrint.i64.f32(float %vecext.5)
190 %vecins.5 = insertelement <8 x i64> %vecins.4, i64 %6, i64 5
191 %vecext.6 = extractelement <8 x float> %0, i64 6
192 %7 = call i64 @llvm.lrint.i64.f32(float %vecext.6)
193 %vecins.6 = insertelement <8 x i64> %vecins.5, i64 %7, i64 6
194 %vecext.7 = extractelement <8 x float> %0, i64 7
195 %8 = call i64 @llvm.lrint.i64.f32(float %vecext.7)
196 %vecins.7 = insertelement <8 x i64> %vecins.6, i64 %8, i64 7
197 ret <8 x i64> %vecins.7
200 define <2 x i64> @llrint_v2i64f32(ptr %a) {
201 ; CHECK-LABEL: define <2 x i64> @llrint_v2i64f32(
202 ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] {
204 ; CHECK-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[A]], align 8
205 ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i64> @llvm.llrint.v2i64.v2f32(<2 x float> [[TMP0]])
206 ; CHECK-NEXT: ret <2 x i64> [[TMP1]]
209 %0 = load <2 x float>, ptr %a
210 %vecext = extractelement <2 x float> %0, i64 0
211 %1 = call i64 @llvm.llrint.i64.f32(float %vecext)
212 %vecins = insertelement <2 x i64> undef, i64 %1, i64 0
213 %vecext.1 = extractelement <2 x float> %0, i64 1
214 %2 = call i64 @llvm.llrint.i64.f32(float %vecext.1)
215 %vecins.1 = insertelement <2 x i64> %vecins, i64 %2, i64 1
216 ret <2 x i64> %vecins.1
219 define <4 x i64> @llrint_v4i64f32(ptr %a) {
220 ; CHECK-LABEL: define <4 x i64> @llrint_v4i64f32(
221 ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] {
223 ; CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[A]], align 16
224 ; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i64> @llvm.llrint.v4i64.v4f32(<4 x float> [[TMP0]])
225 ; CHECK-NEXT: ret <4 x i64> [[TMP1]]
228 %0 = load <4 x float>, ptr %a
229 %vecext = extractelement <4 x float> %0, i64 0
230 %1 = call i64 @llvm.llrint.i64.f32(float %vecext)
231 %vecins = insertelement <4 x i64> undef, i64 %1, i64 0
232 %vecext.1 = extractelement <4 x float> %0, i64 1
233 %2 = call i64 @llvm.llrint.i64.f32(float %vecext.1)
234 %vecins.1 = insertelement <4 x i64> %vecins, i64 %2, i64 1
235 %vecext.2 = extractelement <4 x float> %0, i64 2
236 %3 = call i64 @llvm.llrint.i64.f32(float %vecext.2)
237 %vecins.2 = insertelement <4 x i64> %vecins.1, i64 %3, i64 2
238 %vecext.3 = extractelement <4 x float> %0, i64 3
239 %4 = call i64 @llvm.llrint.i64.f32(float %vecext.3)
240 %vecins.3 = insertelement <4 x i64> %vecins.2, i64 %4, i64 3
241 ret <4 x i64> %vecins.3
244 define <8 x i64> @llrint_v8i64f32(ptr %a) {
245 ; CHECK-LABEL: define <8 x i64> @llrint_v8i64f32(
246 ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] {
248 ; CHECK-NEXT: [[TMP0:%.*]] = load <8 x float>, ptr [[A]], align 32
249 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x float> [[TMP0]], <8 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
250 ; CHECK-NEXT: [[TMP2:%.*]] = call <4 x i64> @llvm.llrint.v4i64.v4f32(<4 x float> [[TMP1]])
251 ; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i64> [[TMP2]], <4 x i64> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
252 ; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <8 x float> [[TMP0]], <8 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
253 ; CHECK-NEXT: [[TMP5:%.*]] = call <4 x i64> @llvm.llrint.v4i64.v4f32(<4 x float> [[TMP4]])
254 ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <4 x i64> [[TMP5]], <4 x i64> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
255 ; CHECK-NEXT: [[VECINS_71:%.*]] = shufflevector <8 x i64> [[TMP3]], <8 x i64> [[TMP6]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
256 ; CHECK-NEXT: ret <8 x i64> [[VECINS_71]]
259 %0 = load <8 x float>, ptr %a
260 %vecext = extractelement <8 x float> %0, i64 0
261 %1 = call i64 @llvm.llrint.i64.f32(float %vecext)
262 %vecins = insertelement <8 x i64> undef, i64 %1, i64 0
263 %vecext.1 = extractelement <8 x float> %0, i64 1
264 %2 = call i64 @llvm.llrint.i64.f32(float %vecext.1)
265 %vecins.1 = insertelement <8 x i64> %vecins, i64 %2, i64 1
266 %vecext.2 = extractelement <8 x float> %0, i64 2
267 %3 = call i64 @llvm.llrint.i64.f32(float %vecext.2)
268 %vecins.2 = insertelement <8 x i64> %vecins.1, i64 %3, i64 2
269 %vecext.3 = extractelement <8 x float> %0, i64 3
270 %4 = call i64 @llvm.llrint.i64.f32(float %vecext.3)
271 %vecins.3 = insertelement <8 x i64> %vecins.2, i64 %4, i64 3
272 %vecext.4 = extractelement <8 x float> %0, i64 4
273 %5 = call i64 @llvm.llrint.i64.f32(float %vecext.4)
274 %vecins.4 = insertelement <8 x i64> %vecins.3, i64 %5, i64 4
275 %vecext.5 = extractelement <8 x float> %0, i64 5
276 %6 = call i64 @llvm.llrint.i64.f32(float %vecext.5)
277 %vecins.5 = insertelement <8 x i64> %vecins.4, i64 %6, i64 5
278 %vecext.6 = extractelement <8 x float> %0, i64 6
279 %7 = call i64 @llvm.llrint.i64.f32(float %vecext.6)
280 %vecins.6 = insertelement <8 x i64> %vecins.5, i64 %7, i64 6
281 %vecext.7 = extractelement <8 x float> %0, i64 7
282 %8 = call i64 @llvm.llrint.i64.f32(float %vecext.7)
283 %vecins.7 = insertelement <8 x i64> %vecins.6, i64 %8, i64 7
284 ret <8 x i64> %vecins.7
287 declare float @llvm.rint.f32(float)
288 declare i32 @llvm.lrint.i32.f32(float)
289 declare i64 @llvm.lrint.i64.f32(float)
290 declare i64 @llvm.llrint.i64.f32(float)