1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -verify-machineinstrs -mattr=+simd128 | FileCheck %s
4 ; Test loads and stores with custom alignment values.
6 target triple = "wasm32-unknown-unknown"
8 ; ==============================================================================
10 ; ==============================================================================
12 define <16 x i8> @load_v16i8_a1(ptr %p) {
13 ; CHECK-LABEL: load_v16i8_a1:
14 ; CHECK: .functype load_v16i8_a1 (i32) -> (v128)
15 ; CHECK-NEXT: # %bb.0:
16 ; CHECK-NEXT: local.get 0
17 ; CHECK-NEXT: v128.load 0:p2align=0
18 ; CHECK-NEXT: # fallthrough-return
19 %v = load <16 x i8>, ptr %p, align 1
23 define <16 x i8> @load_v16i8_a4(ptr %p) {
24 ; CHECK-LABEL: load_v16i8_a4:
25 ; CHECK: .functype load_v16i8_a4 (i32) -> (v128)
26 ; CHECK-NEXT: # %bb.0:
27 ; CHECK-NEXT: local.get 0
28 ; CHECK-NEXT: v128.load 0:p2align=2
29 ; CHECK-NEXT: # fallthrough-return
30 %v = load <16 x i8>, ptr %p, align 4
34 ; 16 is the default alignment for v128 so no attribute is needed.
35 define <16 x i8> @load_v16i8_a16(ptr %p) {
36 ; CHECK-LABEL: load_v16i8_a16:
37 ; CHECK: .functype load_v16i8_a16 (i32) -> (v128)
38 ; CHECK-NEXT: # %bb.0:
39 ; CHECK-NEXT: local.get 0
40 ; CHECK-NEXT: v128.load 0
41 ; CHECK-NEXT: # fallthrough-return
42 %v = load <16 x i8>, ptr %p, align 16
46 ; 32 is greater than the default alignment so it is ignored.
47 define <16 x i8> @load_v16i8_a32(ptr %p) {
48 ; CHECK-LABEL: load_v16i8_a32:
49 ; CHECK: .functype load_v16i8_a32 (i32) -> (v128)
50 ; CHECK-NEXT: # %bb.0:
51 ; CHECK-NEXT: local.get 0
52 ; CHECK-NEXT: v128.load 0
53 ; CHECK-NEXT: # fallthrough-return
54 %v = load <16 x i8>, ptr %p, align 32
58 define void @store_v16i8_a1(ptr %p, <16 x i8> %v) {
59 ; CHECK-LABEL: store_v16i8_a1:
60 ; CHECK: .functype store_v16i8_a1 (i32, v128) -> ()
61 ; CHECK-NEXT: # %bb.0:
62 ; CHECK-NEXT: local.get 0
63 ; CHECK-NEXT: local.get 1
64 ; CHECK-NEXT: v128.store 0:p2align=0
65 ; CHECK-NEXT: # fallthrough-return
66 store <16 x i8> %v, ptr %p, align 1
70 define void @store_v16i8_a4(ptr %p, <16 x i8> %v) {
71 ; CHECK-LABEL: store_v16i8_a4:
72 ; CHECK: .functype store_v16i8_a4 (i32, v128) -> ()
73 ; CHECK-NEXT: # %bb.0:
74 ; CHECK-NEXT: local.get 0
75 ; CHECK-NEXT: local.get 1
76 ; CHECK-NEXT: v128.store 0:p2align=2
77 ; CHECK-NEXT: # fallthrough-return
78 store <16 x i8> %v, ptr %p, align 4
82 ; 16 is the default alignment for v128 so no attribute is needed.
83 define void @store_v16i8_a16(ptr %p, <16 x i8> %v) {
84 ; CHECK-LABEL: store_v16i8_a16:
85 ; CHECK: .functype store_v16i8_a16 (i32, v128) -> ()
86 ; CHECK-NEXT: # %bb.0:
87 ; CHECK-NEXT: local.get 0
88 ; CHECK-NEXT: local.get 1
89 ; CHECK-NEXT: v128.store 0
90 ; CHECK-NEXT: # fallthrough-return
91 store <16 x i8> %v, ptr %p, align 16
95 ; 32 is greater than the default alignment so it is ignored.
96 define void @store_v16i8_a32(ptr %p, <16 x i8> %v) {
97 ; CHECK-LABEL: store_v16i8_a32:
98 ; CHECK: .functype store_v16i8_a32 (i32, v128) -> ()
99 ; CHECK-NEXT: # %bb.0:
100 ; CHECK-NEXT: local.get 0
101 ; CHECK-NEXT: local.get 1
102 ; CHECK-NEXT: v128.store 0
103 ; CHECK-NEXT: # fallthrough-return
104 store <16 x i8> %v, ptr %p, align 32
108 ; 1 is the default alignment for v128.load8_splat so no attribute is needed.
109 define <16 x i8> @load_splat_v16i8_a1(ptr %p) {
110 ; CHECK-LABEL: load_splat_v16i8_a1:
111 ; CHECK: .functype load_splat_v16i8_a1 (i32) -> (v128)
112 ; CHECK-NEXT: # %bb.0:
113 ; CHECK-NEXT: local.get 0
114 ; CHECK-NEXT: v128.load8_splat 0
115 ; CHECK-NEXT: # fallthrough-return
116 %e = load i8, ptr %p, align 1
117 %v1 = insertelement <16 x i8> undef, i8 %e, i32 0
118 %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer
122 ; 2 is greater than the default alignment so it is ignored.
123 define <16 x i8> @load_splat_v16i8_a2(ptr %p) {
124 ; CHECK-LABEL: load_splat_v16i8_a2:
125 ; CHECK: .functype load_splat_v16i8_a2 (i32) -> (v128)
126 ; CHECK-NEXT: # %bb.0:
127 ; CHECK-NEXT: local.get 0
128 ; CHECK-NEXT: v128.load8_splat 0
129 ; CHECK-NEXT: # fallthrough-return
130 %e = load i8, ptr %p, align 2
131 %v1 = insertelement <16 x i8> undef, i8 %e, i32 0
132 %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> zeroinitializer
136 ; 1 is the default alignment for v128.load8_lane so no attribute is needed.
137 define <16 x i8> @load_lane_i8_a1(ptr %p, <16 x i8> %v) {
138 ; CHECK-LABEL: load_lane_i8_a1:
139 ; CHECK: .functype load_lane_i8_a1 (i32, v128) -> (v128)
140 ; CHECK-NEXT: # %bb.0:
141 ; CHECK-NEXT: local.get 0
142 ; CHECK-NEXT: local.get 1
143 ; CHECK-NEXT: v128.load8_lane 0, 0
144 ; CHECK-NEXT: # fallthrough-return
145 %e = load i8, ptr %p, align 1
146 %v1 = insertelement <16 x i8> %v, i8 %e, i32 0
150 ; 2 is greater than the default alignment so it is ignored.
151 define <16 x i8> @load_lane_i8_a2(ptr %p, <16 x i8> %v) {
152 ; CHECK-LABEL: load_lane_i8_a2:
153 ; CHECK: .functype load_lane_i8_a2 (i32, v128) -> (v128)
154 ; CHECK-NEXT: # %bb.0:
155 ; CHECK-NEXT: local.get 0
156 ; CHECK-NEXT: local.get 1
157 ; CHECK-NEXT: v128.load8_lane 0, 0
158 ; CHECK-NEXT: # fallthrough-return
159 %e = load i8, ptr %p, align 2
160 %v1 = insertelement <16 x i8> %v, i8 %e, i32 0
164 ; 1 is the default alignment for v128.store8_lane so no attribute is needed.
165 define void @store_lane_i8_a1(<16 x i8> %v, ptr %p) {
166 ; CHECK-LABEL: store_lane_i8_a1:
167 ; CHECK: .functype store_lane_i8_a1 (v128, i32) -> ()
168 ; CHECK-NEXT: # %bb.0:
169 ; CHECK-NEXT: local.get 1
170 ; CHECK-NEXT: local.get 0
171 ; CHECK-NEXT: v128.store8_lane 0, 0
172 ; CHECK-NEXT: # fallthrough-return
173 %x = extractelement <16 x i8> %v, i32 0
174 store i8 %x, ptr %p, align 1
178 ; 2 is greater than the default alignment so it is ignored.
179 define void @store_lane_i8_a2(<16 x i8> %v, ptr %p) {
180 ; CHECK-LABEL: store_lane_i8_a2:
181 ; CHECK: .functype store_lane_i8_a2 (v128, i32) -> ()
182 ; CHECK-NEXT: # %bb.0:
183 ; CHECK-NEXT: local.get 1
184 ; CHECK-NEXT: local.get 0
185 ; CHECK-NEXT: v128.store8_lane 0, 0
186 ; CHECK-NEXT: # fallthrough-return
187 %x = extractelement <16 x i8> %v, i32 0
188 store i8 %x, ptr %p, align 2
192 ; ==============================================================================
194 ; ==============================================================================
196 define <8 x i16> @load_v8i16_a1(ptr %p) {
197 ; CHECK-LABEL: load_v8i16_a1:
198 ; CHECK: .functype load_v8i16_a1 (i32) -> (v128)
199 ; CHECK-NEXT: # %bb.0:
200 ; CHECK-NEXT: local.get 0
201 ; CHECK-NEXT: v128.load 0:p2align=0
202 ; CHECK-NEXT: # fallthrough-return
203 %v = load <8 x i16>, ptr %p, align 1
207 define <8 x i16> @load_v8i16_a4(ptr %p) {
208 ; CHECK-LABEL: load_v8i16_a4:
209 ; CHECK: .functype load_v8i16_a4 (i32) -> (v128)
210 ; CHECK-NEXT: # %bb.0:
211 ; CHECK-NEXT: local.get 0
212 ; CHECK-NEXT: v128.load 0:p2align=2
213 ; CHECK-NEXT: # fallthrough-return
214 %v = load <8 x i16>, ptr %p, align 4
218 ; 8 is the default alignment for v128 so no attribute is needed.
219 define <8 x i16> @load_v8i16_a16(ptr %p) {
220 ; CHECK-LABEL: load_v8i16_a16:
221 ; CHECK: .functype load_v8i16_a16 (i32) -> (v128)
222 ; CHECK-NEXT: # %bb.0:
223 ; CHECK-NEXT: local.get 0
224 ; CHECK-NEXT: v128.load 0
225 ; CHECK-NEXT: # fallthrough-return
226 %v = load <8 x i16>, ptr %p, align 16
230 ; 32 is greater than the default alignment so it is ignored.
231 define <8 x i16> @load_v8i16_a32(ptr %p) {
232 ; CHECK-LABEL: load_v8i16_a32:
233 ; CHECK: .functype load_v8i16_a32 (i32) -> (v128)
234 ; CHECK-NEXT: # %bb.0:
235 ; CHECK-NEXT: local.get 0
236 ; CHECK-NEXT: v128.load 0
237 ; CHECK-NEXT: # fallthrough-return
238 %v = load <8 x i16>, ptr %p, align 32
242 define void @store_v8i16_a1(ptr %p, <8 x i16> %v) {
243 ; CHECK-LABEL: store_v8i16_a1:
244 ; CHECK: .functype store_v8i16_a1 (i32, v128) -> ()
245 ; CHECK-NEXT: # %bb.0:
246 ; CHECK-NEXT: local.get 0
247 ; CHECK-NEXT: local.get 1
248 ; CHECK-NEXT: v128.store 0:p2align=0
249 ; CHECK-NEXT: # fallthrough-return
250 store <8 x i16> %v, ptr %p, align 1
254 define void @store_v8i16_a4(ptr %p, <8 x i16> %v) {
255 ; CHECK-LABEL: store_v8i16_a4:
256 ; CHECK: .functype store_v8i16_a4 (i32, v128) -> ()
257 ; CHECK-NEXT: # %bb.0:
258 ; CHECK-NEXT: local.get 0
259 ; CHECK-NEXT: local.get 1
260 ; CHECK-NEXT: v128.store 0:p2align=2
261 ; CHECK-NEXT: # fallthrough-return
262 store <8 x i16> %v, ptr %p, align 4
266 ; 16 is the default alignment for v128 so no attribute is needed.
267 define void @store_v8i16_a16(ptr %p, <8 x i16> %v) {
268 ; CHECK-LABEL: store_v8i16_a16:
269 ; CHECK: .functype store_v8i16_a16 (i32, v128) -> ()
270 ; CHECK-NEXT: # %bb.0:
271 ; CHECK-NEXT: local.get 0
272 ; CHECK-NEXT: local.get 1
273 ; CHECK-NEXT: v128.store 0
274 ; CHECK-NEXT: # fallthrough-return
275 store <8 x i16> %v, ptr %p, align 16
279 ; 32 is greater than the default alignment so it is ignored.
280 define void @store_v8i16_a32(ptr %p, <8 x i16> %v) {
281 ; CHECK-LABEL: store_v8i16_a32:
282 ; CHECK: .functype store_v8i16_a32 (i32, v128) -> ()
283 ; CHECK-NEXT: # %bb.0:
284 ; CHECK-NEXT: local.get 0
285 ; CHECK-NEXT: local.get 1
286 ; CHECK-NEXT: v128.store 0
287 ; CHECK-NEXT: # fallthrough-return
288 store <8 x i16> %v, ptr %p, align 32
292 define <8 x i8> @load_ext_v8i16_a1(ptr %p) {
293 ; CHECK-LABEL: load_ext_v8i16_a1:
294 ; CHECK: .functype load_ext_v8i16_a1 (i32) -> (v128)
295 ; CHECK-NEXT: # %bb.0:
296 ; CHECK-NEXT: local.get 0
297 ; CHECK-NEXT: v128.load64_zero 0:p2align=0
298 ; CHECK-NEXT: # fallthrough-return
299 %v = load <8 x i8>, ptr %p, align 1
303 define <8 x i8> @load_ext_v8i16_a2(ptr %p) {
304 ; CHECK-LABEL: load_ext_v8i16_a2:
305 ; CHECK: .functype load_ext_v8i16_a2 (i32) -> (v128)
306 ; CHECK-NEXT: # %bb.0:
307 ; CHECK-NEXT: local.get 0
308 ; CHECK-NEXT: v128.load64_zero 0:p2align=1
309 ; CHECK-NEXT: # fallthrough-return
310 %v = load <8 x i8>, ptr %p, align 2
314 define <8 x i8> @load_ext_v8i16_a4(ptr %p) {
315 ; CHECK-LABEL: load_ext_v8i16_a4:
316 ; CHECK: .functype load_ext_v8i16_a4 (i32) -> (v128)
317 ; CHECK-NEXT: # %bb.0:
318 ; CHECK-NEXT: local.get 0
319 ; CHECK-NEXT: v128.load64_zero 0:p2align=2
320 ; CHECK-NEXT: # fallthrough-return
321 %v = load <8 x i8>, ptr %p, align 4
325 ; 8 is the default alignment for v128 extending load so no attribute is needed.
326 define <8 x i8> @load_ext_v8i16_a8(ptr %p) {
327 ; CHECK-LABEL: load_ext_v8i16_a8:
328 ; CHECK: .functype load_ext_v8i16_a8 (i32) -> (v128)
329 ; CHECK-NEXT: # %bb.0:
330 ; CHECK-NEXT: local.get 0
331 ; CHECK-NEXT: v128.load64_zero 0
332 ; CHECK-NEXT: # fallthrough-return
333 %v = load <8 x i8>, ptr %p, align 8
337 ; 16 is greater than the default alignment so it is ignored.
338 define <8 x i8> @load_ext_v8i16_a16(ptr %p) {
339 ; CHECK-LABEL: load_ext_v8i16_a16:
340 ; CHECK: .functype load_ext_v8i16_a16 (i32) -> (v128)
341 ; CHECK-NEXT: # %bb.0:
342 ; CHECK-NEXT: local.get 0
343 ; CHECK-NEXT: v128.load 0
344 ; CHECK-NEXT: # fallthrough-return
345 %v = load <8 x i8>, ptr %p, align 16
349 define <8 x i16> @load_sext_v8i16_a1(ptr %p) {
350 ; CHECK-LABEL: load_sext_v8i16_a1:
351 ; CHECK: .functype load_sext_v8i16_a1 (i32) -> (v128)
352 ; CHECK-NEXT: # %bb.0:
353 ; CHECK-NEXT: local.get 0
354 ; CHECK-NEXT: i16x8.load8x8_s 0:p2align=0
355 ; CHECK-NEXT: # fallthrough-return
356 %v = load <8 x i8>, ptr %p, align 1
357 %v2 = sext <8 x i8> %v to <8 x i16>
361 define <8 x i16> @load_sext_v8i16_a2(ptr %p) {
362 ; CHECK-LABEL: load_sext_v8i16_a2:
363 ; CHECK: .functype load_sext_v8i16_a2 (i32) -> (v128)
364 ; CHECK-NEXT: # %bb.0:
365 ; CHECK-NEXT: local.get 0
366 ; CHECK-NEXT: i16x8.load8x8_s 0:p2align=1
367 ; CHECK-NEXT: # fallthrough-return
368 %v = load <8 x i8>, ptr %p, align 2
369 %v2 = sext <8 x i8> %v to <8 x i16>
373 define <8 x i16> @load_sext_v8i16_a4(ptr %p) {
374 ; CHECK-LABEL: load_sext_v8i16_a4:
375 ; CHECK: .functype load_sext_v8i16_a4 (i32) -> (v128)
376 ; CHECK-NEXT: # %bb.0:
377 ; CHECK-NEXT: local.get 0
378 ; CHECK-NEXT: i16x8.load8x8_s 0:p2align=2
379 ; CHECK-NEXT: # fallthrough-return
380 %v = load <8 x i8>, ptr %p, align 4
381 %v2 = sext <8 x i8> %v to <8 x i16>
385 ; 8 is the default alignment for v128 extending load so no attribute is needed.
386 define <8 x i16> @load_sext_v8i16_a8(ptr %p) {
387 ; CHECK-LABEL: load_sext_v8i16_a8:
388 ; CHECK: .functype load_sext_v8i16_a8 (i32) -> (v128)
389 ; CHECK-NEXT: # %bb.0:
390 ; CHECK-NEXT: local.get 0
391 ; CHECK-NEXT: i16x8.load8x8_s 0
392 ; CHECK-NEXT: # fallthrough-return
393 %v = load <8 x i8>, ptr %p, align 8
394 %v2 = sext <8 x i8> %v to <8 x i16>
398 ; 16 is greater than the default alignment so it is ignored.
399 define <8 x i16> @load_sext_v8i16_a16(ptr %p) {
400 ; CHECK-LABEL: load_sext_v8i16_a16:
401 ; CHECK: .functype load_sext_v8i16_a16 (i32) -> (v128)
402 ; CHECK-NEXT: # %bb.0:
403 ; CHECK-NEXT: local.get 0
404 ; CHECK-NEXT: i16x8.load8x8_s 0
405 ; CHECK-NEXT: # fallthrough-return
406 %v = load <8 x i8>, ptr %p, align 16
407 %v2 = sext <8 x i8> %v to <8 x i16>
411 define <8 x i16> @load_splat_v8i16_a1(ptr %p) {
412 ; CHECK-LABEL: load_splat_v8i16_a1:
413 ; CHECK: .functype load_splat_v8i16_a1 (i32) -> (v128)
414 ; CHECK-NEXT: # %bb.0:
415 ; CHECK-NEXT: local.get 0
416 ; CHECK-NEXT: v128.load16_splat 0:p2align=0
417 ; CHECK-NEXT: # fallthrough-return
418 %e = load i16, ptr %p, align 1
419 %v1 = insertelement <8 x i16> undef, i16 %e, i32 0
420 %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer
424 ; 2 is the default alignment for v128.load16_splat so no attribute is needed.
425 define <8 x i16> @load_splat_v8i16_a2(ptr %p) {
426 ; CHECK-LABEL: load_splat_v8i16_a2:
427 ; CHECK: .functype load_splat_v8i16_a2 (i32) -> (v128)
428 ; CHECK-NEXT: # %bb.0:
429 ; CHECK-NEXT: local.get 0
430 ; CHECK-NEXT: v128.load16_splat 0
431 ; CHECK-NEXT: # fallthrough-return
432 %e = load i16, ptr %p, align 2
433 %v1 = insertelement <8 x i16> undef, i16 %e, i32 0
434 %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer
438 ; 4 is greater than the default alignment so it is ignored.
439 define <8 x i16> @load_splat_v8i16_a4(ptr %p) {
440 ; CHECK-LABEL: load_splat_v8i16_a4:
441 ; CHECK: .functype load_splat_v8i16_a4 (i32) -> (v128)
442 ; CHECK-NEXT: # %bb.0:
443 ; CHECK-NEXT: local.get 0
444 ; CHECK-NEXT: v128.load16_splat 0
445 ; CHECK-NEXT: # fallthrough-return
446 %e = load i16, ptr %p, align 4
447 %v1 = insertelement <8 x i16> undef, i16 %e, i32 0
448 %v2 = shufflevector <8 x i16> %v1, <8 x i16> undef, <8 x i32> zeroinitializer
452 define <8 x i16> @load_lane_i16_a1(ptr %p, <8 x i16> %v) {
453 ; CHECK-LABEL: load_lane_i16_a1:
454 ; CHECK: .functype load_lane_i16_a1 (i32, v128) -> (v128)
455 ; CHECK-NEXT: # %bb.0:
456 ; CHECK-NEXT: local.get 0
457 ; CHECK-NEXT: local.get 1
458 ; CHECK-NEXT: v128.load16_lane 0:p2align=0, 0
459 ; CHECK-NEXT: # fallthrough-return
460 %e = load i16, ptr %p, align 1
461 %v1 = insertelement <8 x i16> %v, i16 %e, i32 0
465 ; 2 is the default alignment for v128.load16_lane so no attribute is needed.
466 define <8 x i16> @load_lane_i16_a2(ptr %p, <8 x i16> %v) {
467 ; CHECK-LABEL: load_lane_i16_a2:
468 ; CHECK: .functype load_lane_i16_a2 (i32, v128) -> (v128)
469 ; CHECK-NEXT: # %bb.0:
470 ; CHECK-NEXT: local.get 0
471 ; CHECK-NEXT: local.get 1
472 ; CHECK-NEXT: v128.load16_lane 0, 0
473 ; CHECK-NEXT: # fallthrough-return
474 %e = load i16, ptr %p, align 2
475 %v1 = insertelement <8 x i16> %v, i16 %e, i32 0
479 ; 4 is greater than the default alignment so it is ignored.
480 define <8 x i16> @load_lane_i16_a4(ptr %p, <8 x i16> %v) {
481 ; CHECK-LABEL: load_lane_i16_a4:
482 ; CHECK: .functype load_lane_i16_a4 (i32, v128) -> (v128)
483 ; CHECK-NEXT: # %bb.0:
484 ; CHECK-NEXT: local.get 0
485 ; CHECK-NEXT: local.get 1
486 ; CHECK-NEXT: v128.load16_lane 0, 0
487 ; CHECK-NEXT: # fallthrough-return
488 %e = load i16, ptr %p, align 4
489 %v1 = insertelement <8 x i16> %v, i16 %e, i32 0
493 define void @store_lane_i16_a1(<8 x i16> %v, ptr %p) {
494 ; CHECK-LABEL: store_lane_i16_a1:
495 ; CHECK: .functype store_lane_i16_a1 (v128, i32) -> ()
496 ; CHECK-NEXT: # %bb.0:
497 ; CHECK-NEXT: local.get 1
498 ; CHECK-NEXT: local.get 0
499 ; CHECK-NEXT: v128.store16_lane 0:p2align=0, 0
500 ; CHECK-NEXT: # fallthrough-return
501 %x = extractelement <8 x i16> %v, i32 0
502 store i16 %x, ptr %p, align 1
506 ; 2 is the default alignment for v128.store16_lane so no attribute is needed.
507 define void @store_lane_i16_a2(<8 x i16> %v, ptr %p) {
508 ; CHECK-LABEL: store_lane_i16_a2:
509 ; CHECK: .functype store_lane_i16_a2 (v128, i32) -> ()
510 ; CHECK-NEXT: # %bb.0:
511 ; CHECK-NEXT: local.get 1
512 ; CHECK-NEXT: local.get 0
513 ; CHECK-NEXT: v128.store16_lane 0, 0
514 ; CHECK-NEXT: # fallthrough-return
515 %x = extractelement <8 x i16> %v, i32 0
516 store i16 %x, ptr %p, align 2
520 ; 4 is greater than the default alignment so it is ignored.
521 define void @store_lane_i16_a4(<8 x i16> %v, ptr %p) {
522 ; CHECK-LABEL: store_lane_i16_a4:
523 ; CHECK: .functype store_lane_i16_a4 (v128, i32) -> ()
524 ; CHECK-NEXT: # %bb.0:
525 ; CHECK-NEXT: local.get 1
526 ; CHECK-NEXT: local.get 0
527 ; CHECK-NEXT: v128.store16_lane 0, 0
528 ; CHECK-NEXT: # fallthrough-return
529 %x = extractelement <8 x i16> %v, i32 0
530 store i16 %x, ptr %p, align 4
534 ; ==============================================================================
536 ; ==============================================================================
538 define <4 x i32> @load_v4i32_a1(ptr %p) {
539 ; CHECK-LABEL: load_v4i32_a1:
540 ; CHECK: .functype load_v4i32_a1 (i32) -> (v128)
541 ; CHECK-NEXT: # %bb.0:
542 ; CHECK-NEXT: local.get 0
543 ; CHECK-NEXT: v128.load 0:p2align=0
544 ; CHECK-NEXT: # fallthrough-return
545 %v = load <4 x i32>, ptr %p, align 1
549 define <4 x i32> @load_v4i32_a4(ptr %p) {
550 ; CHECK-LABEL: load_v4i32_a4:
551 ; CHECK: .functype load_v4i32_a4 (i32) -> (v128)
552 ; CHECK-NEXT: # %bb.0:
553 ; CHECK-NEXT: local.get 0
554 ; CHECK-NEXT: v128.load 0:p2align=2
555 ; CHECK-NEXT: # fallthrough-return
556 %v = load <4 x i32>, ptr %p, align 4
560 ; 4 is the default alignment for v128 so no attribute is needed.
561 define <4 x i32> @load_v4i32_a16(ptr %p) {
562 ; CHECK-LABEL: load_v4i32_a16:
563 ; CHECK: .functype load_v4i32_a16 (i32) -> (v128)
564 ; CHECK-NEXT: # %bb.0:
565 ; CHECK-NEXT: local.get 0
566 ; CHECK-NEXT: v128.load 0
567 ; CHECK-NEXT: # fallthrough-return
568 %v = load <4 x i32>, ptr %p, align 16
572 ; 32 is greater than the default alignment so it is ignored.
573 define <4 x i32> @load_v4i32_a32(ptr %p) {
574 ; CHECK-LABEL: load_v4i32_a32:
575 ; CHECK: .functype load_v4i32_a32 (i32) -> (v128)
576 ; CHECK-NEXT: # %bb.0:
577 ; CHECK-NEXT: local.get 0
578 ; CHECK-NEXT: v128.load 0
579 ; CHECK-NEXT: # fallthrough-return
580 %v = load <4 x i32>, ptr %p, align 32
584 define void @store_v4i32_a1(ptr %p, <4 x i32> %v) {
585 ; CHECK-LABEL: store_v4i32_a1:
586 ; CHECK: .functype store_v4i32_a1 (i32, v128) -> ()
587 ; CHECK-NEXT: # %bb.0:
588 ; CHECK-NEXT: local.get 0
589 ; CHECK-NEXT: local.get 1
590 ; CHECK-NEXT: v128.store 0:p2align=0
591 ; CHECK-NEXT: # fallthrough-return
592 store <4 x i32> %v, ptr %p, align 1
596 define void @store_v4i32_a4(ptr %p, <4 x i32> %v) {
597 ; CHECK-LABEL: store_v4i32_a4:
598 ; CHECK: .functype store_v4i32_a4 (i32, v128) -> ()
599 ; CHECK-NEXT: # %bb.0:
600 ; CHECK-NEXT: local.get 0
601 ; CHECK-NEXT: local.get 1
602 ; CHECK-NEXT: v128.store 0:p2align=2
603 ; CHECK-NEXT: # fallthrough-return
604 store <4 x i32> %v, ptr %p, align 4
608 ; 16 is the default alignment for v128 so no attribute is needed.
609 define void @store_v4i32_a16(ptr %p, <4 x i32> %v) {
610 ; CHECK-LABEL: store_v4i32_a16:
611 ; CHECK: .functype store_v4i32_a16 (i32, v128) -> ()
612 ; CHECK-NEXT: # %bb.0:
613 ; CHECK-NEXT: local.get 0
614 ; CHECK-NEXT: local.get 1
615 ; CHECK-NEXT: v128.store 0
616 ; CHECK-NEXT: # fallthrough-return
617 store <4 x i32> %v, ptr %p, align 16
621 ; 32 is greater than the default alignment so it is ignored.
622 define void @store_v4i32_a32(ptr %p, <4 x i32> %v) {
623 ; CHECK-LABEL: store_v4i32_a32:
624 ; CHECK: .functype store_v4i32_a32 (i32, v128) -> ()
625 ; CHECK-NEXT: # %bb.0:
626 ; CHECK-NEXT: local.get 0
627 ; CHECK-NEXT: local.get 1
628 ; CHECK-NEXT: v128.store 0
629 ; CHECK-NEXT: # fallthrough-return
630 store <4 x i32> %v, ptr %p, align 32
634 define <4 x i16> @load_ext_v4i32_a1(ptr %p) {
635 ; CHECK-LABEL: load_ext_v4i32_a1:
636 ; CHECK: .functype load_ext_v4i32_a1 (i32) -> (v128)
637 ; CHECK-NEXT: # %bb.0:
638 ; CHECK-NEXT: local.get 0
639 ; CHECK-NEXT: v128.load64_zero 0:p2align=0
640 ; CHECK-NEXT: # fallthrough-return
641 %v = load <4 x i16>, ptr %p, align 1
645 define <4 x i16> @load_ext_v4i32_a2(ptr %p) {
646 ; CHECK-LABEL: load_ext_v4i32_a2:
647 ; CHECK: .functype load_ext_v4i32_a2 (i32) -> (v128)
648 ; CHECK-NEXT: # %bb.0:
649 ; CHECK-NEXT: local.get 0
650 ; CHECK-NEXT: v128.load64_zero 0:p2align=1
651 ; CHECK-NEXT: # fallthrough-return
652 %v = load <4 x i16>, ptr %p, align 2
656 define <4 x i16> @load_ext_v4i32_a4(ptr %p) {
657 ; CHECK-LABEL: load_ext_v4i32_a4:
658 ; CHECK: .functype load_ext_v4i32_a4 (i32) -> (v128)
659 ; CHECK-NEXT: # %bb.0:
660 ; CHECK-NEXT: local.get 0
661 ; CHECK-NEXT: v128.load64_zero 0:p2align=2
662 ; CHECK-NEXT: # fallthrough-return
663 %v = load <4 x i16>, ptr %p, align 4
667 ; 8 is the default alignment for v128 extending load so no attribute is needed.
668 define <4 x i16> @load_ext_v4i32_a8(ptr %p) {
669 ; CHECK-LABEL: load_ext_v4i32_a8:
670 ; CHECK: .functype load_ext_v4i32_a8 (i32) -> (v128)
671 ; CHECK-NEXT: # %bb.0:
672 ; CHECK-NEXT: local.get 0
673 ; CHECK-NEXT: v128.load64_zero 0
674 ; CHECK-NEXT: # fallthrough-return
675 %v = load <4 x i16>, ptr %p, align 8
679 ; 16 is greater than the default alignment so it is ignored.
680 define <4 x i16> @load_ext_v4i32_a16(ptr %p) {
681 ; CHECK-LABEL: load_ext_v4i32_a16:
682 ; CHECK: .functype load_ext_v4i32_a16 (i32) -> (v128)
683 ; CHECK-NEXT: # %bb.0:
684 ; CHECK-NEXT: local.get 0
685 ; CHECK-NEXT: v128.load 0
686 ; CHECK-NEXT: # fallthrough-return
687 %v = load <4 x i16>, ptr %p, align 16
691 define <4 x i32> @load_sext_v4i32_a1(ptr %p) {
692 ; CHECK-LABEL: load_sext_v4i32_a1:
693 ; CHECK: .functype load_sext_v4i32_a1 (i32) -> (v128)
694 ; CHECK-NEXT: # %bb.0:
695 ; CHECK-NEXT: local.get 0
696 ; CHECK-NEXT: i32x4.load16x4_s 0:p2align=0
697 ; CHECK-NEXT: # fallthrough-return
698 %v = load <4 x i16>, ptr %p, align 1
699 %v2 = sext <4 x i16> %v to <4 x i32>
703 define <4 x i32> @load_sext_v4i32_a2(ptr %p) {
704 ; CHECK-LABEL: load_sext_v4i32_a2:
705 ; CHECK: .functype load_sext_v4i32_a2 (i32) -> (v128)
706 ; CHECK-NEXT: # %bb.0:
707 ; CHECK-NEXT: local.get 0
708 ; CHECK-NEXT: i32x4.load16x4_s 0:p2align=1
709 ; CHECK-NEXT: # fallthrough-return
710 %v = load <4 x i16>, ptr %p, align 2
711 %v2 = sext <4 x i16> %v to <4 x i32>
715 define <4 x i32> @load_sext_v4i32_a4(ptr %p) {
716 ; CHECK-LABEL: load_sext_v4i32_a4:
717 ; CHECK: .functype load_sext_v4i32_a4 (i32) -> (v128)
718 ; CHECK-NEXT: # %bb.0:
719 ; CHECK-NEXT: local.get 0
720 ; CHECK-NEXT: i32x4.load16x4_s 0:p2align=2
721 ; CHECK-NEXT: # fallthrough-return
722 %v = load <4 x i16>, ptr %p, align 4
723 %v2 = sext <4 x i16> %v to <4 x i32>
727 ; 8 is the default alignment for v128 extending load so no attribute is needed.
728 define <4 x i32> @load_sext_v4i32_a8(ptr %p) {
729 ; CHECK-LABEL: load_sext_v4i32_a8:
730 ; CHECK: .functype load_sext_v4i32_a8 (i32) -> (v128)
731 ; CHECK-NEXT: # %bb.0:
732 ; CHECK-NEXT: local.get 0
733 ; CHECK-NEXT: i32x4.load16x4_s 0
734 ; CHECK-NEXT: # fallthrough-return
735 %v = load <4 x i16>, ptr %p, align 8
736 %v2 = sext <4 x i16> %v to <4 x i32>
740 ; 16 is greater than the default alignment so it is ignored.
741 define <4 x i32> @load_sext_v4i32_a16(ptr %p) {
742 ; CHECK-LABEL: load_sext_v4i32_a16:
743 ; CHECK: .functype load_sext_v4i32_a16 (i32) -> (v128)
744 ; CHECK-NEXT: # %bb.0:
745 ; CHECK-NEXT: local.get 0
746 ; CHECK-NEXT: i32x4.load16x4_s 0
747 ; CHECK-NEXT: # fallthrough-return
748 %v = load <4 x i16>, ptr %p, align 16
749 %v2 = sext <4 x i16> %v to <4 x i32>
753 define <4 x i32> @load_splat_v4i32_a1(ptr %addr) {
754 ; CHECK-LABEL: load_splat_v4i32_a1:
755 ; CHECK: .functype load_splat_v4i32_a1 (i32) -> (v128)
756 ; CHECK-NEXT: # %bb.0:
757 ; CHECK-NEXT: local.get 0
758 ; CHECK-NEXT: v128.load32_splat 0:p2align=0
759 ; CHECK-NEXT: # fallthrough-return
760 %e = load i32, ptr %addr, align 1
761 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
762 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
766 define <4 x i32> @load_splat_v4i32_a2(ptr %addr) {
767 ; CHECK-LABEL: load_splat_v4i32_a2:
768 ; CHECK: .functype load_splat_v4i32_a2 (i32) -> (v128)
769 ; CHECK-NEXT: # %bb.0:
770 ; CHECK-NEXT: local.get 0
771 ; CHECK-NEXT: v128.load32_splat 0:p2align=1
772 ; CHECK-NEXT: # fallthrough-return
773 %e = load i32, ptr %addr, align 2
774 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
775 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
779 ; 4 is the default alignment for v128.load32_splat so no attribute is needed.
780 define <4 x i32> @load_splat_v4i32_a4(ptr %addr) {
781 ; CHECK-LABEL: load_splat_v4i32_a4:
782 ; CHECK: .functype load_splat_v4i32_a4 (i32) -> (v128)
783 ; CHECK-NEXT: # %bb.0:
784 ; CHECK-NEXT: local.get 0
785 ; CHECK-NEXT: v128.load32_splat 0
786 ; CHECK-NEXT: # fallthrough-return
787 %e = load i32, ptr %addr, align 4
788 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
789 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
793 ; 8 is greater than the default alignment so it is ignored.
794 define <4 x i32> @load_splat_v4i32_a8(ptr %addr) {
795 ; CHECK-LABEL: load_splat_v4i32_a8:
796 ; CHECK: .functype load_splat_v4i32_a8 (i32) -> (v128)
797 ; CHECK-NEXT: # %bb.0:
798 ; CHECK-NEXT: local.get 0
799 ; CHECK-NEXT: v128.load32_splat 0
800 ; CHECK-NEXT: # fallthrough-return
801 %e = load i32, ptr %addr, align 8
802 %v1 = insertelement <4 x i32> undef, i32 %e, i32 0
803 %v2 = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> zeroinitializer
807 define <4 x i32> @load_lane_i32_a1(ptr %p, <4 x i32> %v) {
808 ; CHECK-LABEL: load_lane_i32_a1:
809 ; CHECK: .functype load_lane_i32_a1 (i32, v128) -> (v128)
810 ; CHECK-NEXT: # %bb.0:
811 ; CHECK-NEXT: local.get 0
812 ; CHECK-NEXT: local.get 1
813 ; CHECK-NEXT: v128.load32_lane 0:p2align=0, 0
814 ; CHECK-NEXT: # fallthrough-return
815 %e = load i32, ptr %p, align 1
816 %v1 = insertelement <4 x i32> %v, i32 %e, i32 0
820 define <4 x i32> @load_lane_i32_a2(ptr %p, <4 x i32> %v) {
821 ; CHECK-LABEL: load_lane_i32_a2:
822 ; CHECK: .functype load_lane_i32_a2 (i32, v128) -> (v128)
823 ; CHECK-NEXT: # %bb.0:
824 ; CHECK-NEXT: local.get 0
825 ; CHECK-NEXT: local.get 1
826 ; CHECK-NEXT: v128.load32_lane 0:p2align=1, 0
827 ; CHECK-NEXT: # fallthrough-return
828 %e = load i32, ptr %p, align 2
829 %v1 = insertelement <4 x i32> %v, i32 %e, i32 0
833 ; 4 is the default alignment for v128.load32_lane so no attribute is needed.
834 define <4 x i32> @load_lane_i32_a4(ptr %p, <4 x i32> %v) {
835 ; CHECK-LABEL: load_lane_i32_a4:
836 ; CHECK: .functype load_lane_i32_a4 (i32, v128) -> (v128)
837 ; CHECK-NEXT: # %bb.0:
838 ; CHECK-NEXT: local.get 0
839 ; CHECK-NEXT: local.get 1
840 ; CHECK-NEXT: v128.load32_lane 0, 0
841 ; CHECK-NEXT: # fallthrough-return
842 %e = load i32, ptr %p, align 4
843 %v1 = insertelement <4 x i32> %v, i32 %e, i32 0
847 ; 8 is greater than the default alignment so it is ignored.
848 define <4 x i32> @load_lane_i32_a8(ptr %p, <4 x i32> %v) {
849 ; CHECK-LABEL: load_lane_i32_a8:
850 ; CHECK: .functype load_lane_i32_a8 (i32, v128) -> (v128)
851 ; CHECK-NEXT: # %bb.0:
852 ; CHECK-NEXT: local.get 0
853 ; CHECK-NEXT: local.get 1
854 ; CHECK-NEXT: v128.load32_lane 0, 0
855 ; CHECK-NEXT: # fallthrough-return
856 %e = load i32, ptr %p, align 8
857 %v1 = insertelement <4 x i32> %v, i32 %e, i32 0
861 define void @store_lane_i32_a1(<4 x i32> %v, ptr %p) {
862 ; CHECK-LABEL: store_lane_i32_a1:
863 ; CHECK: .functype store_lane_i32_a1 (v128, i32) -> ()
864 ; CHECK-NEXT: # %bb.0:
865 ; CHECK-NEXT: local.get 1
866 ; CHECK-NEXT: local.get 0
867 ; CHECK-NEXT: v128.store32_lane 0:p2align=0, 0
868 ; CHECK-NEXT: # fallthrough-return
869 %x = extractelement <4 x i32> %v, i32 0
870 store i32 %x, ptr %p, align 1
874 define void @store_lane_i32_a2(<4 x i32> %v, ptr %p) {
875 ; CHECK-LABEL: store_lane_i32_a2:
876 ; CHECK: .functype store_lane_i32_a2 (v128, i32) -> ()
877 ; CHECK-NEXT: # %bb.0:
878 ; CHECK-NEXT: local.get 1
879 ; CHECK-NEXT: local.get 0
880 ; CHECK-NEXT: v128.store32_lane 0:p2align=1, 0
881 ; CHECK-NEXT: # fallthrough-return
882 %x = extractelement <4 x i32> %v, i32 0
883 store i32 %x, ptr %p, align 2
887 ; 4 is the default alignment for v128.store32_lane so no attribute is needed.
888 define void @store_lane_i32_a4(<4 x i32> %v, ptr %p) {
889 ; CHECK-LABEL: store_lane_i32_a4:
890 ; CHECK: .functype store_lane_i32_a4 (v128, i32) -> ()
891 ; CHECK-NEXT: # %bb.0:
892 ; CHECK-NEXT: local.get 1
893 ; CHECK-NEXT: local.get 0
894 ; CHECK-NEXT: v128.store32_lane 0, 0
895 ; CHECK-NEXT: # fallthrough-return
896 %x = extractelement <4 x i32> %v, i32 0
897 store i32 %x, ptr %p, align 4
901 ; 8 is greater than the default alignment so it is ignored.
902 define void @store_lane_i32_a8(<4 x i32> %v, ptr %p) {
903 ; CHECK-LABEL: store_lane_i32_a8:
904 ; CHECK: .functype store_lane_i32_a8 (v128, i32) -> ()
905 ; CHECK-NEXT: # %bb.0:
906 ; CHECK-NEXT: local.get 1
907 ; CHECK-NEXT: local.get 0
908 ; CHECK-NEXT: v128.store32_lane 0, 0
909 ; CHECK-NEXT: # fallthrough-return
910 %x = extractelement <4 x i32> %v, i32 0
911 store i32 %x, ptr %p, align 8
915 define <4 x i32> @load_zero_i32_a1(ptr %p) {
916 ; CHECK-LABEL: load_zero_i32_a1:
917 ; CHECK: .functype load_zero_i32_a1 (i32) -> (v128)
918 ; CHECK-NEXT: # %bb.0:
919 ; CHECK-NEXT: local.get 0
920 ; CHECK-NEXT: v128.load32_zero 0:p2align=0
921 ; CHECK-NEXT: # fallthrough-return
922 %x = load i32, ptr %p, align 1
923 %v = insertelement <4 x i32> zeroinitializer, i32 %x, i32 0
927 define <4 x i32> @load_zero_i32_a2(ptr %p) {
928 ; CHECK-LABEL: load_zero_i32_a2:
929 ; CHECK: .functype load_zero_i32_a2 (i32) -> (v128)
930 ; CHECK-NEXT: # %bb.0:
931 ; CHECK-NEXT: local.get 0
932 ; CHECK-NEXT: v128.load32_zero 0:p2align=1
933 ; CHECK-NEXT: # fallthrough-return
934 %x = load i32, ptr %p, align 2
935 %v = insertelement <4 x i32> zeroinitializer, i32 %x, i32 0
939 ; 4 is the default alignment for v128.load32_zero so no attribute is needed.
940 define <4 x i32> @load_zero_i32_a4(ptr %p) {
941 ; CHECK-LABEL: load_zero_i32_a4:
942 ; CHECK: .functype load_zero_i32_a4 (i32) -> (v128)
943 ; CHECK-NEXT: # %bb.0:
944 ; CHECK-NEXT: local.get 0
945 ; CHECK-NEXT: v128.load32_zero 0
946 ; CHECK-NEXT: # fallthrough-return
947 %x = load i32, ptr %p, align 4
948 %v = insertelement <4 x i32> zeroinitializer, i32 %x, i32 0
952 ; 8 is greater than the default alignment so it is ignored.
953 define <4 x i32> @load_zero_i32_a8(ptr %p) {
954 ; CHECK-LABEL: load_zero_i32_a8:
955 ; CHECK: .functype load_zero_i32_a8 (i32) -> (v128)
956 ; CHECK-NEXT: # %bb.0:
957 ; CHECK-NEXT: local.get 0
958 ; CHECK-NEXT: v128.load32_zero 0
959 ; CHECK-NEXT: # fallthrough-return
960 %x = load i32, ptr %p, align 8
961 %v = insertelement <4 x i32> zeroinitializer, i32 %x, i32 0
965 ; ==============================================================================
967 ; ==============================================================================
969 define <2 x i64> @load_v2i64_a1(ptr %p) {
970 ; CHECK-LABEL: load_v2i64_a1:
971 ; CHECK: .functype load_v2i64_a1 (i32) -> (v128)
972 ; CHECK-NEXT: # %bb.0:
973 ; CHECK-NEXT: local.get 0
974 ; CHECK-NEXT: v128.load 0:p2align=0
975 ; CHECK-NEXT: # fallthrough-return
976 %v = load <2 x i64>, ptr %p, align 1
980 define <2 x i64> @load_v2i64_a4(ptr %p) {
981 ; CHECK-LABEL: load_v2i64_a4:
982 ; CHECK: .functype load_v2i64_a4 (i32) -> (v128)
983 ; CHECK-NEXT: # %bb.0:
984 ; CHECK-NEXT: local.get 0
985 ; CHECK-NEXT: v128.load 0:p2align=2
986 ; CHECK-NEXT: # fallthrough-return
987 %v = load <2 x i64>, ptr %p, align 4
991 ; 2 is the default alignment for v128 so no attribute is needed.
992 define <2 x i64> @load_v2i64_a16(ptr %p) {
993 ; CHECK-LABEL: load_v2i64_a16:
994 ; CHECK: .functype load_v2i64_a16 (i32) -> (v128)
995 ; CHECK-NEXT: # %bb.0:
996 ; CHECK-NEXT: local.get 0
997 ; CHECK-NEXT: v128.load 0
998 ; CHECK-NEXT: # fallthrough-return
999 %v = load <2 x i64>, ptr %p, align 16
1003 ; 32 is greater than the default alignment so it is ignored.
1004 define <2 x i64> @load_v2i64_a32(ptr %p) {
1005 ; CHECK-LABEL: load_v2i64_a32:
1006 ; CHECK: .functype load_v2i64_a32 (i32) -> (v128)
1007 ; CHECK-NEXT: # %bb.0:
1008 ; CHECK-NEXT: local.get 0
1009 ; CHECK-NEXT: v128.load 0
1010 ; CHECK-NEXT: # fallthrough-return
1011 %v = load <2 x i64>, ptr %p, align 32
1015 define void @store_v2i64_a1(ptr %p, <2 x i64> %v) {
1016 ; CHECK-LABEL: store_v2i64_a1:
1017 ; CHECK: .functype store_v2i64_a1 (i32, v128) -> ()
1018 ; CHECK-NEXT: # %bb.0:
1019 ; CHECK-NEXT: local.get 0
1020 ; CHECK-NEXT: local.get 1
1021 ; CHECK-NEXT: v128.store 0:p2align=0
1022 ; CHECK-NEXT: # fallthrough-return
1023 store <2 x i64> %v, ptr %p, align 1
1027 define void @store_v2i64_a4(ptr %p, <2 x i64> %v) {
1028 ; CHECK-LABEL: store_v2i64_a4:
1029 ; CHECK: .functype store_v2i64_a4 (i32, v128) -> ()
1030 ; CHECK-NEXT: # %bb.0:
1031 ; CHECK-NEXT: local.get 0
1032 ; CHECK-NEXT: local.get 1
1033 ; CHECK-NEXT: v128.store 0:p2align=2
1034 ; CHECK-NEXT: # fallthrough-return
1035 store <2 x i64> %v, ptr %p, align 4
1039 ; 16 is the default alignment for v128 so no attribute is needed.
1040 define void @store_v2i64_a16(ptr %p, <2 x i64> %v) {
1041 ; CHECK-LABEL: store_v2i64_a16:
1042 ; CHECK: .functype store_v2i64_a16 (i32, v128) -> ()
1043 ; CHECK-NEXT: # %bb.0:
1044 ; CHECK-NEXT: local.get 0
1045 ; CHECK-NEXT: local.get 1
1046 ; CHECK-NEXT: v128.store 0
1047 ; CHECK-NEXT: # fallthrough-return
1048 store <2 x i64> %v, ptr %p, align 16
1052 ; 32 is greater than the default alignment so it is ignored.
1053 define void @store_v2i64_a32(ptr %p, <2 x i64> %v) {
1054 ; CHECK-LABEL: store_v2i64_a32:
1055 ; CHECK: .functype store_v2i64_a32 (i32, v128) -> ()
1056 ; CHECK-NEXT: # %bb.0:
1057 ; CHECK-NEXT: local.get 0
1058 ; CHECK-NEXT: local.get 1
1059 ; CHECK-NEXT: v128.store 0
1060 ; CHECK-NEXT: # fallthrough-return
1061 store <2 x i64> %v, ptr %p, align 32
1065 define <2 x i64> @load_splat_v2i64_a1(ptr %p) {
1066 ; CHECK-LABEL: load_splat_v2i64_a1:
1067 ; CHECK: .functype load_splat_v2i64_a1 (i32) -> (v128)
1068 ; CHECK-NEXT: # %bb.0:
1069 ; CHECK-NEXT: local.get 0
1070 ; CHECK-NEXT: v128.load64_splat 0:p2align=0
1071 ; CHECK-NEXT: # fallthrough-return
1072 %e = load i64, ptr %p, align 1
1073 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
1074 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
1078 define <2 x i64> @load_splat_v2i64_a2(ptr %p) {
1079 ; CHECK-LABEL: load_splat_v2i64_a2:
1080 ; CHECK: .functype load_splat_v2i64_a2 (i32) -> (v128)
1081 ; CHECK-NEXT: # %bb.0:
1082 ; CHECK-NEXT: local.get 0
1083 ; CHECK-NEXT: v128.load64_splat 0:p2align=1
1084 ; CHECK-NEXT: # fallthrough-return
1085 %e = load i64, ptr %p, align 2
1086 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
1087 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
1091 define <2 x i64> @load_splat_v2i64_a4(ptr %p) {
1092 ; CHECK-LABEL: load_splat_v2i64_a4:
1093 ; CHECK: .functype load_splat_v2i64_a4 (i32) -> (v128)
1094 ; CHECK-NEXT: # %bb.0:
1095 ; CHECK-NEXT: local.get 0
1096 ; CHECK-NEXT: v128.load64_splat 0:p2align=2
1097 ; CHECK-NEXT: # fallthrough-return
1098 %e = load i64, ptr %p, align 4
1099 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
1100 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
1104 ; 8 is the default alignment for v128.load64_splat so no attribute is needed.
1105 define <2 x i64> @load_splat_v2i64_a8(ptr %p) {
1106 ; CHECK-LABEL: load_splat_v2i64_a8:
1107 ; CHECK: .functype load_splat_v2i64_a8 (i32) -> (v128)
1108 ; CHECK-NEXT: # %bb.0:
1109 ; CHECK-NEXT: local.get 0
1110 ; CHECK-NEXT: v128.load64_splat 0
1111 ; CHECK-NEXT: # fallthrough-return
1112 %e = load i64, ptr %p, align 8
1113 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
1114 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
1118 ; 16 is greater than the default alignment so it is ignored.
1119 define <2 x i64> @load_splat_v2i64_a16(ptr %p) {
1120 ; CHECK-LABEL: load_splat_v2i64_a16:
1121 ; CHECK: .functype load_splat_v2i64_a16 (i32) -> (v128)
1122 ; CHECK-NEXT: # %bb.0:
1123 ; CHECK-NEXT: local.get 0
1124 ; CHECK-NEXT: v128.load64_splat 0
1125 ; CHECK-NEXT: # fallthrough-return
1126 %e = load i64, ptr %p, align 16
1127 %v1 = insertelement <2 x i64> undef, i64 %e, i32 0
1128 %v2 = shufflevector <2 x i64> %v1, <2 x i64> undef, <2 x i32> zeroinitializer
1132 define <2 x i64> @load_lane_i64_a1(ptr %p, <2 x i64> %v) {
1133 ; CHECK-LABEL: load_lane_i64_a1:
1134 ; CHECK: .functype load_lane_i64_a1 (i32, v128) -> (v128)
1135 ; CHECK-NEXT: # %bb.0:
1136 ; CHECK-NEXT: local.get 0
1137 ; CHECK-NEXT: local.get 1
1138 ; CHECK-NEXT: v128.load64_lane 0:p2align=0, 0
1139 ; CHECK-NEXT: # fallthrough-return
1140 %e = load i64, ptr %p, align 1
1141 %v1 = insertelement <2 x i64> %v, i64 %e, i32 0
1145 define <2 x i64> @load_lane_i64_a2(ptr %p, <2 x i64> %v) {
1146 ; CHECK-LABEL: load_lane_i64_a2:
1147 ; CHECK: .functype load_lane_i64_a2 (i32, v128) -> (v128)
1148 ; CHECK-NEXT: # %bb.0:
1149 ; CHECK-NEXT: local.get 0
1150 ; CHECK-NEXT: local.get 1
1151 ; CHECK-NEXT: v128.load64_lane 0:p2align=1, 0
1152 ; CHECK-NEXT: # fallthrough-return
1153 %e = load i64, ptr %p, align 2
1154 %v1 = insertelement <2 x i64> %v, i64 %e, i32 0
1158 define <2 x i64> @load_lane_i64_a4(ptr %p, <2 x i64> %v) {
1159 ; CHECK-LABEL: load_lane_i64_a4:
1160 ; CHECK: .functype load_lane_i64_a4 (i32, v128) -> (v128)
1161 ; CHECK-NEXT: # %bb.0:
1162 ; CHECK-NEXT: local.get 0
1163 ; CHECK-NEXT: local.get 1
1164 ; CHECK-NEXT: v128.load64_lane 0:p2align=2, 0
1165 ; CHECK-NEXT: # fallthrough-return
1166 %e = load i64, ptr %p, align 4
1167 %v1 = insertelement <2 x i64> %v, i64 %e, i32 0
1171 ; 8 is the default alignment for v128.load64_lane so no attribute is needed.
1172 define <2 x i64> @load_lane_i64_a8(ptr %p, <2 x i64> %v) {
1173 ; CHECK-LABEL: load_lane_i64_a8:
1174 ; CHECK: .functype load_lane_i64_a8 (i32, v128) -> (v128)
1175 ; CHECK-NEXT: # %bb.0:
1176 ; CHECK-NEXT: local.get 0
1177 ; CHECK-NEXT: local.get 1
1178 ; CHECK-NEXT: v128.load64_lane 0, 0
1179 ; CHECK-NEXT: # fallthrough-return
1180 %e = load i64, ptr %p, align 8
1181 %v1 = insertelement <2 x i64> %v, i64 %e, i32 0
1185 ; 16 is greater than the default alignment so it is ignored.
1186 define <2 x i64> @load_lane_i64_a16(ptr %p, <2 x i64> %v) {
1187 ; CHECK-LABEL: load_lane_i64_a16:
1188 ; CHECK: .functype load_lane_i64_a16 (i32, v128) -> (v128)
1189 ; CHECK-NEXT: # %bb.0:
1190 ; CHECK-NEXT: local.get 0
1191 ; CHECK-NEXT: local.get 1
1192 ; CHECK-NEXT: v128.load64_lane 0, 0
1193 ; CHECK-NEXT: # fallthrough-return
1194 %e = load i64, ptr %p, align 16
1195 %v1 = insertelement <2 x i64> %v, i64 %e, i32 0
1199 define void @store_lane_i64_a1(<2 x i64> %v, ptr %p) {
1200 ; CHECK-LABEL: store_lane_i64_a1:
1201 ; CHECK: .functype store_lane_i64_a1 (v128, i32) -> ()
1202 ; CHECK-NEXT: # %bb.0:
1203 ; CHECK-NEXT: local.get 1
1204 ; CHECK-NEXT: local.get 0
1205 ; CHECK-NEXT: v128.store64_lane 0:p2align=0, 0
1206 ; CHECK-NEXT: # fallthrough-return
1207 %x = extractelement <2 x i64> %v, i32 0
1208 store i64 %x, ptr %p, align 1
1212 define void @store_lane_i64_a2(<2 x i64> %v, ptr %p) {
1213 ; CHECK-LABEL: store_lane_i64_a2:
1214 ; CHECK: .functype store_lane_i64_a2 (v128, i32) -> ()
1215 ; CHECK-NEXT: # %bb.0:
1216 ; CHECK-NEXT: local.get 1
1217 ; CHECK-NEXT: local.get 0
1218 ; CHECK-NEXT: v128.store64_lane 0:p2align=1, 0
1219 ; CHECK-NEXT: # fallthrough-return
1220 %x = extractelement <2 x i64> %v, i32 0
1221 store i64 %x, ptr %p, align 2
1225 define void @store_lane_i64_a4(<2 x i64> %v, ptr %p) {
1226 ; CHECK-LABEL: store_lane_i64_a4:
1227 ; CHECK: .functype store_lane_i64_a4 (v128, i32) -> ()
1228 ; CHECK-NEXT: # %bb.0:
1229 ; CHECK-NEXT: local.get 1
1230 ; CHECK-NEXT: local.get 0
1231 ; CHECK-NEXT: v128.store64_lane 0:p2align=2, 0
1232 ; CHECK-NEXT: # fallthrough-return
1233 %x = extractelement <2 x i64> %v, i32 0
1234 store i64 %x, ptr %p, align 4
1238 ; 8 is the default alignment for v128.store64_lane so no attribute is needed.
1239 define void @store_lane_i64_a8(<2 x i64> %v, ptr %p) {
1240 ; CHECK-LABEL: store_lane_i64_a8:
1241 ; CHECK: .functype store_lane_i64_a8 (v128, i32) -> ()
1242 ; CHECK-NEXT: # %bb.0:
1243 ; CHECK-NEXT: local.get 1
1244 ; CHECK-NEXT: local.get 0
1245 ; CHECK-NEXT: v128.store64_lane 0, 0
1246 ; CHECK-NEXT: # fallthrough-return
1247 %x = extractelement <2 x i64> %v, i32 0
1248 store i64 %x, ptr %p, align 8
1252 ; 16 is greater than the default alignment so it is ignored.
1253 define void @store_lane_i64_a16(<2 x i64> %v, ptr %p) {
1254 ; CHECK-LABEL: store_lane_i64_a16:
1255 ; CHECK: .functype store_lane_i64_a16 (v128, i32) -> ()
1256 ; CHECK-NEXT: # %bb.0:
1257 ; CHECK-NEXT: local.get 1
1258 ; CHECK-NEXT: local.get 0
1259 ; CHECK-NEXT: v128.store64_lane 0, 0
1260 ; CHECK-NEXT: # fallthrough-return
1261 %x = extractelement <2 x i64> %v, i32 0
1262 store i64 %x, ptr %p, align 16
1266 define <2 x i64> @load_zero_i64_a1(ptr %p) {
1267 ; CHECK-LABEL: load_zero_i64_a1:
1268 ; CHECK: .functype load_zero_i64_a1 (i32) -> (v128)
1269 ; CHECK-NEXT: # %bb.0:
1270 ; CHECK-NEXT: local.get 0
1271 ; CHECK-NEXT: v128.load64_zero 0:p2align=0
1272 ; CHECK-NEXT: # fallthrough-return
1273 %x = load i64, ptr %p, align 1
1274 %v = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0
1278 define <2 x i64> @load_zero_i64_a2(ptr %p) {
1279 ; CHECK-LABEL: load_zero_i64_a2:
1280 ; CHECK: .functype load_zero_i64_a2 (i32) -> (v128)
1281 ; CHECK-NEXT: # %bb.0:
1282 ; CHECK-NEXT: local.get 0
1283 ; CHECK-NEXT: v128.load64_zero 0:p2align=1
1284 ; CHECK-NEXT: # fallthrough-return
1285 %x = load i64, ptr %p, align 2
1286 %v = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0
1290 define <2 x i64> @load_zero_i64_a4(ptr %p) {
1291 ; CHECK-LABEL: load_zero_i64_a4:
1292 ; CHECK: .functype load_zero_i64_a4 (i32) -> (v128)
1293 ; CHECK-NEXT: # %bb.0:
1294 ; CHECK-NEXT: local.get 0
1295 ; CHECK-NEXT: v128.load64_zero 0:p2align=2
1296 ; CHECK-NEXT: # fallthrough-return
1297 %x = load i64, ptr %p, align 4
1298 %v = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0
1302 ; 8 is the default alignment for v128.load64_zero so no attribute is needed.
1303 define <2 x i64> @load_zero_i64_a8(ptr %p) {
1304 ; CHECK-LABEL: load_zero_i64_a8:
1305 ; CHECK: .functype load_zero_i64_a8 (i32) -> (v128)
1306 ; CHECK-NEXT: # %bb.0:
1307 ; CHECK-NEXT: local.get 0
1308 ; CHECK-NEXT: v128.load64_zero 0
1309 ; CHECK-NEXT: # fallthrough-return
1310 %x = load i64, ptr %p, align 8
1311 %v = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0
1315 ; 16 is greater than the default alignment so it is ignored.
1316 define <2 x i64> @load_zero_i64_a16(ptr %p) {
1317 ; CHECK-LABEL: load_zero_i64_a16:
1318 ; CHECK: .functype load_zero_i64_a16 (i32) -> (v128)
1319 ; CHECK-NEXT: # %bb.0:
1320 ; CHECK-NEXT: local.get 0
1321 ; CHECK-NEXT: v128.load64_zero 0
1322 ; CHECK-NEXT: # fallthrough-return
1323 %x = load i64, ptr %p, align 16
1324 %v = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0
1328 ; ==============================================================================
1330 ; ==============================================================================
1332 define <4 x float> @load_v4f32_a1(ptr %p) {
1333 ; CHECK-LABEL: load_v4f32_a1:
1334 ; CHECK: .functype load_v4f32_a1 (i32) -> (v128)
1335 ; CHECK-NEXT: # %bb.0:
1336 ; CHECK-NEXT: local.get 0
1337 ; CHECK-NEXT: v128.load 0:p2align=0
1338 ; CHECK-NEXT: # fallthrough-return
1339 %v = load <4 x float>, ptr %p, align 1
1343 define <4 x float> @load_v4f32_a4(ptr %p) {
1344 ; CHECK-LABEL: load_v4f32_a4:
1345 ; CHECK: .functype load_v4f32_a4 (i32) -> (v128)
1346 ; CHECK-NEXT: # %bb.0:
1347 ; CHECK-NEXT: local.get 0
1348 ; CHECK-NEXT: v128.load 0:p2align=2
1349 ; CHECK-NEXT: # fallthrough-return
1350 %v = load <4 x float>, ptr %p, align 4
1354 ; 4 is the default alignment for v128 so no attribute is needed.
1355 define <4 x float> @load_v4f32_a16(ptr %p) {
1356 ; CHECK-LABEL: load_v4f32_a16:
1357 ; CHECK: .functype load_v4f32_a16 (i32) -> (v128)
1358 ; CHECK-NEXT: # %bb.0:
1359 ; CHECK-NEXT: local.get 0
1360 ; CHECK-NEXT: v128.load 0
1361 ; CHECK-NEXT: # fallthrough-return
1362 %v = load <4 x float>, ptr %p, align 16
1366 ; 32 is greater than the default alignment so it is ignored.
1367 define <4 x float> @load_v4f32_a32(ptr %p) {
1368 ; CHECK-LABEL: load_v4f32_a32:
1369 ; CHECK: .functype load_v4f32_a32 (i32) -> (v128)
1370 ; CHECK-NEXT: # %bb.0:
1371 ; CHECK-NEXT: local.get 0
1372 ; CHECK-NEXT: v128.load 0
1373 ; CHECK-NEXT: # fallthrough-return
1374 %v = load <4 x float>, ptr %p, align 32
1378 define void @store_v4f32_a1(ptr %p, <4 x float> %v) {
1379 ; CHECK-LABEL: store_v4f32_a1:
1380 ; CHECK: .functype store_v4f32_a1 (i32, v128) -> ()
1381 ; CHECK-NEXT: # %bb.0:
1382 ; CHECK-NEXT: local.get 0
1383 ; CHECK-NEXT: local.get 1
1384 ; CHECK-NEXT: v128.store 0:p2align=0
1385 ; CHECK-NEXT: # fallthrough-return
1386 store <4 x float> %v, ptr %p, align 1
1390 define void @store_v4f32_a4(ptr %p, <4 x float> %v) {
1391 ; CHECK-LABEL: store_v4f32_a4:
1392 ; CHECK: .functype store_v4f32_a4 (i32, v128) -> ()
1393 ; CHECK-NEXT: # %bb.0:
1394 ; CHECK-NEXT: local.get 0
1395 ; CHECK-NEXT: local.get 1
1396 ; CHECK-NEXT: v128.store 0:p2align=2
1397 ; CHECK-NEXT: # fallthrough-return
1398 store <4 x float> %v, ptr %p, align 4
1402 ; 16 is the default alignment for v128 so no attribute is needed.
1403 define void @store_v4f32_a16(ptr %p, <4 x float> %v) {
1404 ; CHECK-LABEL: store_v4f32_a16:
1405 ; CHECK: .functype store_v4f32_a16 (i32, v128) -> ()
1406 ; CHECK-NEXT: # %bb.0:
1407 ; CHECK-NEXT: local.get 0
1408 ; CHECK-NEXT: local.get 1
1409 ; CHECK-NEXT: v128.store 0
1410 ; CHECK-NEXT: # fallthrough-return
1411 store <4 x float> %v, ptr %p, align 16
1415 ; 32 is greater than the default alignment so it is ignored.
1416 define void @store_v4f32_a32(ptr %p, <4 x float> %v) {
1417 ; CHECK-LABEL: store_v4f32_a32:
1418 ; CHECK: .functype store_v4f32_a32 (i32, v128) -> ()
1419 ; CHECK-NEXT: # %bb.0:
1420 ; CHECK-NEXT: local.get 0
1421 ; CHECK-NEXT: local.get 1
1422 ; CHECK-NEXT: v128.store 0
1423 ; CHECK-NEXT: # fallthrough-return
1424 store <4 x float> %v, ptr %p, align 32
1428 ; ==============================================================================
1430 ; ==============================================================================
1432 define <2 x double> @load_v2f64_a1(ptr %p) {
1433 ; CHECK-LABEL: load_v2f64_a1:
1434 ; CHECK: .functype load_v2f64_a1 (i32) -> (v128)
1435 ; CHECK-NEXT: # %bb.0:
1436 ; CHECK-NEXT: local.get 0
1437 ; CHECK-NEXT: v128.load 0:p2align=0
1438 ; CHECK-NEXT: # fallthrough-return
1439 %v = load <2 x double>, ptr %p, align 1
1443 define <2 x double> @load_v2f64_a4(ptr %p) {
1444 ; CHECK-LABEL: load_v2f64_a4:
1445 ; CHECK: .functype load_v2f64_a4 (i32) -> (v128)
1446 ; CHECK-NEXT: # %bb.0:
1447 ; CHECK-NEXT: local.get 0
1448 ; CHECK-NEXT: v128.load 0:p2align=2
1449 ; CHECK-NEXT: # fallthrough-return
1450 %v = load <2 x double>, ptr %p, align 4
1454 ; 2 is the default alignment for v128 so no attribute is needed.
1455 define <2 x double> @load_v2f64_a16(ptr %p) {
1456 ; CHECK-LABEL: load_v2f64_a16:
1457 ; CHECK: .functype load_v2f64_a16 (i32) -> (v128)
1458 ; CHECK-NEXT: # %bb.0:
1459 ; CHECK-NEXT: local.get 0
1460 ; CHECK-NEXT: v128.load 0
1461 ; CHECK-NEXT: # fallthrough-return
1462 %v = load <2 x double>, ptr %p, align 16
1466 ; 32 is greater than the default alignment so it is ignored.
1467 define <2 x double> @load_v2f64_a32(ptr %p) {
1468 ; CHECK-LABEL: load_v2f64_a32:
1469 ; CHECK: .functype load_v2f64_a32 (i32) -> (v128)
1470 ; CHECK-NEXT: # %bb.0:
1471 ; CHECK-NEXT: local.get 0
1472 ; CHECK-NEXT: v128.load 0
1473 ; CHECK-NEXT: # fallthrough-return
1474 %v = load <2 x double>, ptr %p, align 32
1478 define void @store_v2f64_a1(ptr %p, <2 x double> %v) {
1479 ; CHECK-LABEL: store_v2f64_a1:
1480 ; CHECK: .functype store_v2f64_a1 (i32, v128) -> ()
1481 ; CHECK-NEXT: # %bb.0:
1482 ; CHECK-NEXT: local.get 0
1483 ; CHECK-NEXT: local.get 1
1484 ; CHECK-NEXT: v128.store 0:p2align=0
1485 ; CHECK-NEXT: # fallthrough-return
1486 store <2 x double> %v, ptr %p, align 1
1490 define void @store_v2f64_a4(ptr %p, <2 x double> %v) {
1491 ; CHECK-LABEL: store_v2f64_a4:
1492 ; CHECK: .functype store_v2f64_a4 (i32, v128) -> ()
1493 ; CHECK-NEXT: # %bb.0:
1494 ; CHECK-NEXT: local.get 0
1495 ; CHECK-NEXT: local.get 1
1496 ; CHECK-NEXT: v128.store 0:p2align=2
1497 ; CHECK-NEXT: # fallthrough-return
1498 store <2 x double> %v, ptr %p, align 4
1502 ; 16 is the default alignment for v128 so no attribute is needed.
1503 define void @store_v2f64_a16(ptr %p, <2 x double> %v) {
1504 ; CHECK-LABEL: store_v2f64_a16:
1505 ; CHECK: .functype store_v2f64_a16 (i32, v128) -> ()
1506 ; CHECK-NEXT: # %bb.0:
1507 ; CHECK-NEXT: local.get 0
1508 ; CHECK-NEXT: local.get 1
1509 ; CHECK-NEXT: v128.store 0
1510 ; CHECK-NEXT: # fallthrough-return
1511 store <2 x double> %v, ptr %p, align 16
1515 ; 32 is greater than the default alignment so it is ignored.
1516 define void @store_v2f64_a32(ptr %p, <2 x double> %v) {
1517 ; CHECK-LABEL: store_v2f64_a32:
1518 ; CHECK: .functype store_v2f64_a32 (i32, v128) -> ()
1519 ; CHECK-NEXT: # %bb.0:
1520 ; CHECK-NEXT: local.get 0
1521 ; CHECK-NEXT: local.get 1
1522 ; CHECK-NEXT: v128.store 0
1523 ; CHECK-NEXT: # fallthrough-return
1524 store <2 x double> %v, ptr %p, align 32