Skip to content

Commit b61232e

Browse files
committedOct 31, 2018
[WebAssembly] Process p2align operands for SIMD loads and stores
Reviewers: aheejin, dschuff Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D53886 llvm-svn: 345795
1 parent 6ff31fe commit b61232e

File tree

3 files changed

+642
-96
lines changed

3 files changed

+642
-96
lines changed
 

‎llvm/lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) {
8989
case WebAssembly::LOAD_I64:
9090
case WebAssembly::LOAD_F32:
9191
case WebAssembly::LOAD_F64:
92+
case WebAssembly::LOAD_v16i8:
93+
case WebAssembly::LOAD_v8i16:
94+
case WebAssembly::LOAD_v4i32:
95+
case WebAssembly::LOAD_v2i64:
96+
case WebAssembly::LOAD_v4f32:
97+
case WebAssembly::LOAD_v2f64:
9298
case WebAssembly::LOAD8_S_I32:
9399
case WebAssembly::LOAD8_U_I32:
94100
case WebAssembly::LOAD16_S_I32:
@@ -164,6 +170,12 @@ bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) {
164170
case WebAssembly::STORE_I64:
165171
case WebAssembly::STORE_F32:
166172
case WebAssembly::STORE_F64:
173+
case WebAssembly::STORE_v16i8:
174+
case WebAssembly::STORE_v8i16:
175+
case WebAssembly::STORE_v4i32:
176+
case WebAssembly::STORE_v2i64:
177+
case WebAssembly::STORE_v4f32:
178+
case WebAssembly::STORE_v2f64:
167179
case WebAssembly::STORE8_I32:
168180
case WebAssembly::STORE16_I32:
169181
case WebAssembly::STORE8_I64:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,534 @@
1+
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -wasm-enable-unimplemented-simd -mattr=+simd128 | FileCheck %s
2+
3+
; Test loads and stores with custom alignment values.
4+
5+
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
6+
target triple = "wasm32-unknown-unknown"
7+
8+
; ==============================================================================
9+
; 16 x i8
10+
; ==============================================================================
11+
12+
; CHECK-LABEL: load_v16i8_a1:
13+
; CHECK-NEXT: .param i32{{$}}
14+
; CHECK-NEXT: .result v128{{$}}
15+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}}
16+
; CHECK-NEXT: return $pop[[R]]{{$}}
17+
define <16 x i8> @load_v16i8_a1(<16 x i8> *%p) {
18+
%v = load <16 x i8>, <16 x i8>* %p, align 1
19+
ret <16 x i8> %v
20+
}
21+
22+
; CHECK-LABEL: load_v16i8_a4:
23+
; CHECK-NEXT: .param i32{{$}}
24+
; CHECK-NEXT: .result v128{{$}}
25+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}}
26+
; CHECK-NEXT: return $pop[[R]]{{$}}
27+
define <16 x i8> @load_v16i8_a4(<16 x i8> *%p) {
28+
%v = load <16 x i8>, <16 x i8>* %p, align 4
29+
ret <16 x i8> %v
30+
}
31+
32+
; 16 is the default alignment for v128 so no attribute is needed.
33+
34+
; CHECK-LABEL: load_v16i8_a16:
35+
; CHECK-NEXT: .param i32{{$}}
36+
; CHECK-NEXT: .result v128{{$}}
37+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
38+
; CHECK-NEXT: return $pop[[R]]{{$}}
39+
define <16 x i8> @load_v16i8_a16(<16 x i8> *%p) {
40+
%v = load <16 x i8>, <16 x i8>* %p, align 16
41+
ret <16 x i8> %v
42+
}
43+
44+
; 32 is greater than the default alignment so it is ignored.
45+
46+
; CHECK-LABEL: load_v16i8_a32:
47+
; CHECK-NEXT: .param i32{{$}}
48+
; CHECK-NEXT: .result v128{{$}}
49+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
50+
; CHECK-NEXT: return $pop[[R]]{{$}}
51+
define <16 x i8> @load_v16i8_a32(<16 x i8> *%p) {
52+
%v = load <16 x i8>, <16 x i8>* %p, align 32
53+
ret <16 x i8> %v
54+
}
55+
56+
; CHECK-LABEL: store_v16i8_a1:
57+
; CHECK-NEXT: .param i32, v128{{$}}
58+
; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}}
59+
; CHECK-NEXT: return{{$}}
60+
define void @store_v16i8_a1(<16 x i8> *%p, <16 x i8> %v) {
61+
store <16 x i8> %v, <16 x i8>* %p, align 1
62+
ret void
63+
}
64+
65+
; CHECK-LABEL: store_v16i8_a4:
66+
; CHECK-NEXT: .param i32, v128{{$}}
67+
; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}}
68+
; CHECK-NEXT: return{{$}}
69+
define void @store_v16i8_a4(<16 x i8> *%p, <16 x i8> %v) {
70+
store <16 x i8> %v, <16 x i8>* %p, align 4
71+
ret void
72+
}
73+
74+
; 16 is the default alignment for v128 so no attribute is needed.
75+
76+
; CHECK-LABEL: store_v16i8_a16:
77+
; CHECK-NEXT: .param i32, v128{{$}}
78+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
79+
; CHECK-NEXT: return{{$}}
80+
define void @store_v16i8_a16(<16 x i8> *%p, <16 x i8> %v) {
81+
store <16 x i8> %v, <16 x i8>* %p, align 16
82+
ret void
83+
}
84+
85+
; 32 is greater than the default alignment so it is ignored.
86+
87+
; CHECK-LABEL: store_v16i8_a32:
88+
; CHECK-NEXT: .param i32, v128{{$}}
89+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
90+
; CHECK-NEXT: return{{$}}
91+
define void @store_v16i8_a32(<16 x i8> *%p, <16 x i8> %v) {
92+
store <16 x i8> %v, <16 x i8>* %p, align 32
93+
ret void
94+
}
95+
96+
; ==============================================================================
97+
; 8 x i16
98+
; ==============================================================================
99+
100+
; CHECK-LABEL: load_v8i16_a1:
101+
; CHECK-NEXT: .param i32{{$}}
102+
; CHECK-NEXT: .result v128{{$}}
103+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}}
104+
; CHECK-NEXT: return $pop[[R]]{{$}}
105+
define <8 x i16> @load_v8i16_a1(<8 x i16> *%p) {
106+
%v = load <8 x i16>, <8 x i16>* %p, align 1
107+
ret <8 x i16> %v
108+
}
109+
110+
; CHECK-LABEL: load_v8i16_a4:
111+
; CHECK-NEXT: .param i32{{$}}
112+
; CHECK-NEXT: .result v128{{$}}
113+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}}
114+
; CHECK-NEXT: return $pop[[R]]{{$}}
115+
define <8 x i16> @load_v8i16_a4(<8 x i16> *%p) {
116+
%v = load <8 x i16>, <8 x i16>* %p, align 4
117+
ret <8 x i16> %v
118+
}
119+
120+
; 8 is the default alignment for v128 so no attribute is needed.
121+
122+
; CHECK-LABEL: load_v8i16_a16:
123+
; CHECK-NEXT: .param i32{{$}}
124+
; CHECK-NEXT: .result v128{{$}}
125+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
126+
; CHECK-NEXT: return $pop[[R]]{{$}}
127+
define <8 x i16> @load_v8i16_a16(<8 x i16> *%p) {
128+
%v = load <8 x i16>, <8 x i16>* %p, align 16
129+
ret <8 x i16> %v
130+
}
131+
132+
; 32 is greater than the default alignment so it is ignored.
133+
134+
; CHECK-LABEL: load_v8i16_a32:
135+
; CHECK-NEXT: .param i32{{$}}
136+
; CHECK-NEXT: .result v128{{$}}
137+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
138+
; CHECK-NEXT: return $pop[[R]]{{$}}
139+
define <8 x i16> @load_v8i16_a32(<8 x i16> *%p) {
140+
%v = load <8 x i16>, <8 x i16>* %p, align 32
141+
ret <8 x i16> %v
142+
}
143+
144+
; CHECK-LABEL: store_v8i16_a1:
145+
; CHECK-NEXT: .param i32, v128{{$}}
146+
; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}}
147+
; CHECK-NEXT: return{{$}}
148+
define void @store_v8i16_a1(<8 x i16> *%p, <8 x i16> %v) {
149+
store <8 x i16> %v, <8 x i16>* %p, align 1
150+
ret void
151+
}
152+
153+
; CHECK-LABEL: store_v8i16_a4:
154+
; CHECK-NEXT: .param i32, v128{{$}}
155+
; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}}
156+
; CHECK-NEXT: return{{$}}
157+
define void @store_v8i16_a4(<8 x i16> *%p, <8 x i16> %v) {
158+
store <8 x i16> %v, <8 x i16>* %p, align 4
159+
ret void
160+
}
161+
162+
; 16 is the default alignment for v128 so no attribute is needed.
163+
164+
; CHECK-LABEL: store_v8i16_a16:
165+
; CHECK-NEXT: .param i32, v128{{$}}
166+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
167+
; CHECK-NEXT: return{{$}}
168+
define void @store_v8i16_a16(<8 x i16> *%p, <8 x i16> %v) {
169+
store <8 x i16> %v, <8 x i16>* %p, align 16
170+
ret void
171+
}
172+
173+
; 32 is greater than the default alignment so it is ignored.
174+
175+
; CHECK-LABEL: store_v8i16_a32:
176+
; CHECK-NEXT: .param i32, v128{{$}}
177+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
178+
; CHECK-NEXT: return{{$}}
179+
define void @store_v8i16_a32(<8 x i16> *%p, <8 x i16> %v) {
180+
store <8 x i16> %v, <8 x i16>* %p, align 32
181+
ret void
182+
}
183+
184+
; ==============================================================================
185+
; 4 x i32
186+
; ==============================================================================
187+
188+
; CHECK-LABEL: load_v4i32_a1:
189+
; CHECK-NEXT: .param i32{{$}}
190+
; CHECK-NEXT: .result v128{{$}}
191+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}}
192+
; CHECK-NEXT: return $pop[[R]]{{$}}
193+
define <4 x i32> @load_v4i32_a1(<4 x i32> *%p) {
194+
%v = load <4 x i32>, <4 x i32>* %p, align 1
195+
ret <4 x i32> %v
196+
}
197+
198+
; CHECK-LABEL: load_v4i32_a4:
199+
; CHECK-NEXT: .param i32{{$}}
200+
; CHECK-NEXT: .result v128{{$}}
201+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}}
202+
; CHECK-NEXT: return $pop[[R]]{{$}}
203+
define <4 x i32> @load_v4i32_a4(<4 x i32> *%p) {
204+
%v = load <4 x i32>, <4 x i32>* %p, align 4
205+
ret <4 x i32> %v
206+
}
207+
208+
; 4 is the default alignment for v128 so no attribute is needed.
209+
210+
; CHECK-LABEL: load_v4i32_a16:
211+
; CHECK-NEXT: .param i32{{$}}
212+
; CHECK-NEXT: .result v128{{$}}
213+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
214+
; CHECK-NEXT: return $pop[[R]]{{$}}
215+
define <4 x i32> @load_v4i32_a16(<4 x i32> *%p) {
216+
%v = load <4 x i32>, <4 x i32>* %p, align 16
217+
ret <4 x i32> %v
218+
}
219+
220+
; 32 is greater than the default alignment so it is ignored.
221+
222+
; CHECK-LABEL: load_v4i32_a32:
223+
; CHECK-NEXT: .param i32{{$}}
224+
; CHECK-NEXT: .result v128{{$}}
225+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
226+
; CHECK-NEXT: return $pop[[R]]{{$}}
227+
define <4 x i32> @load_v4i32_a32(<4 x i32> *%p) {
228+
%v = load <4 x i32>, <4 x i32>* %p, align 32
229+
ret <4 x i32> %v
230+
}
231+
232+
; CHECK-LABEL: store_v4i32_a1:
233+
; CHECK-NEXT: .param i32, v128{{$}}
234+
; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}}
235+
; CHECK-NEXT: return{{$}}
236+
define void @store_v4i32_a1(<4 x i32> *%p, <4 x i32> %v) {
237+
store <4 x i32> %v, <4 x i32>* %p, align 1
238+
ret void
239+
}
240+
241+
; CHECK-LABEL: store_v4i32_a4:
242+
; CHECK-NEXT: .param i32, v128{{$}}
243+
; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}}
244+
; CHECK-NEXT: return{{$}}
245+
define void @store_v4i32_a4(<4 x i32> *%p, <4 x i32> %v) {
246+
store <4 x i32> %v, <4 x i32>* %p, align 4
247+
ret void
248+
}
249+
250+
; 16 is the default alignment for v128 so no attribute is needed.
251+
252+
; CHECK-LABEL: store_v4i32_a16:
253+
; CHECK-NEXT: .param i32, v128{{$}}
254+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
255+
; CHECK-NEXT: return{{$}}
256+
define void @store_v4i32_a16(<4 x i32> *%p, <4 x i32> %v) {
257+
store <4 x i32> %v, <4 x i32>* %p, align 16
258+
ret void
259+
}
260+
261+
; 32 is greater than the default alignment so it is ignored.
262+
263+
; CHECK-LABEL: store_v4i32_a32:
264+
; CHECK-NEXT: .param i32, v128{{$}}
265+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
266+
; CHECK-NEXT: return{{$}}
267+
define void @store_v4i32_a32(<4 x i32> *%p, <4 x i32> %v) {
268+
store <4 x i32> %v, <4 x i32>* %p, align 32
269+
ret void
270+
}
271+
272+
; ==============================================================================
273+
; 2 x i64
274+
; ==============================================================================
275+
276+
; CHECK-LABEL: load_v2i64_a1:
277+
; CHECK-NEXT: .param i32{{$}}
278+
; CHECK-NEXT: .result v128{{$}}
279+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}}
280+
; CHECK-NEXT: return $pop[[R]]{{$}}
281+
define <2 x i64> @load_v2i64_a1(<2 x i64> *%p) {
282+
%v = load <2 x i64>, <2 x i64>* %p, align 1
283+
ret <2 x i64> %v
284+
}
285+
286+
; CHECK-LABEL: load_v2i64_a4:
287+
; CHECK-NEXT: .param i32{{$}}
288+
; CHECK-NEXT: .result v128{{$}}
289+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}}
290+
; CHECK-NEXT: return $pop[[R]]{{$}}
291+
define <2 x i64> @load_v2i64_a4(<2 x i64> *%p) {
292+
%v = load <2 x i64>, <2 x i64>* %p, align 4
293+
ret <2 x i64> %v
294+
}
295+
296+
; 2 is the default alignment for v128 so no attribute is needed.
297+
298+
; CHECK-LABEL: load_v2i64_a16:
299+
; CHECK-NEXT: .param i32{{$}}
300+
; CHECK-NEXT: .result v128{{$}}
301+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
302+
; CHECK-NEXT: return $pop[[R]]{{$}}
303+
define <2 x i64> @load_v2i64_a16(<2 x i64> *%p) {
304+
%v = load <2 x i64>, <2 x i64>* %p, align 16
305+
ret <2 x i64> %v
306+
}
307+
308+
; 32 is greater than the default alignment so it is ignored.
309+
310+
; CHECK-LABEL: load_v2i64_a32:
311+
; CHECK-NEXT: .param i32{{$}}
312+
; CHECK-NEXT: .result v128{{$}}
313+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
314+
; CHECK-NEXT: return $pop[[R]]{{$}}
315+
define <2 x i64> @load_v2i64_a32(<2 x i64> *%p) {
316+
%v = load <2 x i64>, <2 x i64>* %p, align 32
317+
ret <2 x i64> %v
318+
}
319+
320+
; CHECK-LABEL: store_v2i64_a1:
321+
; CHECK-NEXT: .param i32, v128{{$}}
322+
; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}}
323+
; CHECK-NEXT: return{{$}}
324+
define void @store_v2i64_a1(<2 x i64> *%p, <2 x i64> %v) {
325+
store <2 x i64> %v, <2 x i64>* %p, align 1
326+
ret void
327+
}
328+
329+
; CHECK-LABEL: store_v2i64_a4:
330+
; CHECK-NEXT: .param i32, v128{{$}}
331+
; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}}
332+
; CHECK-NEXT: return{{$}}
333+
define void @store_v2i64_a4(<2 x i64> *%p, <2 x i64> %v) {
334+
store <2 x i64> %v, <2 x i64>* %p, align 4
335+
ret void
336+
}
337+
338+
; 16 is the default alignment for v128 so no attribute is needed.
339+
340+
; CHECK-LABEL: store_v2i64_a16:
341+
; CHECK-NEXT: .param i32, v128{{$}}
342+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
343+
; CHECK-NEXT: return{{$}}
344+
define void @store_v2i64_a16(<2 x i64> *%p, <2 x i64> %v) {
345+
store <2 x i64> %v, <2 x i64>* %p, align 16
346+
ret void
347+
}
348+
349+
; 32 is greater than the default alignment so it is ignored.
350+
351+
; CHECK-LABEL: store_v2i64_a32:
352+
; CHECK-NEXT: .param i32, v128{{$}}
353+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
354+
; CHECK-NEXT: return{{$}}
355+
define void @store_v2i64_a32(<2 x i64> *%p, <2 x i64> %v) {
356+
store <2 x i64> %v, <2 x i64>* %p, align 32
357+
ret void
358+
}
359+
360+
; ==============================================================================
361+
; 4 x float
362+
; ==============================================================================
363+
364+
; CHECK-LABEL: load_v4f32_a1:
365+
; CHECK-NEXT: .param i32{{$}}
366+
; CHECK-NEXT: .result v128{{$}}
367+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}}
368+
; CHECK-NEXT: return $pop[[R]]{{$}}
369+
define <4 x float> @load_v4f32_a1(<4 x float> *%p) {
370+
%v = load <4 x float>, <4 x float>* %p, align 1
371+
ret <4 x float> %v
372+
}
373+
374+
; CHECK-LABEL: load_v4f32_a4:
375+
; CHECK-NEXT: .param i32{{$}}
376+
; CHECK-NEXT: .result v128{{$}}
377+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}}
378+
; CHECK-NEXT: return $pop[[R]]{{$}}
379+
define <4 x float> @load_v4f32_a4(<4 x float> *%p) {
380+
%v = load <4 x float>, <4 x float>* %p, align 4
381+
ret <4 x float> %v
382+
}
383+
384+
; 4 is the default alignment for v128 so no attribute is needed.
385+
386+
; CHECK-LABEL: load_v4f32_a16:
387+
; CHECK-NEXT: .param i32{{$}}
388+
; CHECK-NEXT: .result v128{{$}}
389+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
390+
; CHECK-NEXT: return $pop[[R]]{{$}}
391+
define <4 x float> @load_v4f32_a16(<4 x float> *%p) {
392+
%v = load <4 x float>, <4 x float>* %p, align 16
393+
ret <4 x float> %v
394+
}
395+
396+
; 32 is greater than the default alignment so it is ignored.
397+
398+
; CHECK-LABEL: load_v4f32_a32:
399+
; CHECK-NEXT: .param i32{{$}}
400+
; CHECK-NEXT: .result v128{{$}}
401+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
402+
; CHECK-NEXT: return $pop[[R]]{{$}}
403+
define <4 x float> @load_v4f32_a32(<4 x float> *%p) {
404+
%v = load <4 x float>, <4 x float>* %p, align 32
405+
ret <4 x float> %v
406+
}
407+
408+
; CHECK-LABEL: store_v4f32_a1:
409+
; CHECK-NEXT: .param i32, v128{{$}}
410+
; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}}
411+
; CHECK-NEXT: return{{$}}
412+
define void @store_v4f32_a1(<4 x float> *%p, <4 x float> %v) {
413+
store <4 x float> %v, <4 x float>* %p, align 1
414+
ret void
415+
}
416+
417+
; CHECK-LABEL: store_v4f32_a4:
418+
; CHECK-NEXT: .param i32, v128{{$}}
419+
; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}}
420+
; CHECK-NEXT: return{{$}}
421+
define void @store_v4f32_a4(<4 x float> *%p, <4 x float> %v) {
422+
store <4 x float> %v, <4 x float>* %p, align 4
423+
ret void
424+
}
425+
426+
; 16 is the default alignment for v128 so no attribute is needed.
427+
428+
; CHECK-LABEL: store_v4f32_a16:
429+
; CHECK-NEXT: .param i32, v128{{$}}
430+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
431+
; CHECK-NEXT: return{{$}}
432+
define void @store_v4f32_a16(<4 x float> *%p, <4 x float> %v) {
433+
store <4 x float> %v, <4 x float>* %p, align 16
434+
ret void
435+
}
436+
437+
; 32 is greater than the default alignment so it is ignored.
438+
439+
; CHECK-LABEL: store_v4f32_a32:
440+
; CHECK-NEXT: .param i32, v128{{$}}
441+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
442+
; CHECK-NEXT: return{{$}}
443+
define void @store_v4f32_a32(<4 x float> *%p, <4 x float> %v) {
444+
store <4 x float> %v, <4 x float>* %p, align 32
445+
ret void
446+
}
447+
448+
; ==============================================================================
449+
; 2 x double
450+
; ==============================================================================
451+
452+
; CHECK-LABEL: load_v2f64_a1:
453+
; CHECK-NEXT: .param i32{{$}}
454+
; CHECK-NEXT: .result v128{{$}}
455+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=0{{$}}
456+
; CHECK-NEXT: return $pop[[R]]{{$}}
457+
define <2 x double> @load_v2f64_a1(<2 x double> *%p) {
458+
%v = load <2 x double>, <2 x double>* %p, align 1
459+
ret <2 x double> %v
460+
}
461+
462+
; CHECK-LABEL: load_v2f64_a4:
463+
; CHECK-NEXT: .param i32{{$}}
464+
; CHECK-NEXT: .result v128{{$}}
465+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0):p2align=2{{$}}
466+
; CHECK-NEXT: return $pop[[R]]{{$}}
467+
define <2 x double> @load_v2f64_a4(<2 x double> *%p) {
468+
%v = load <2 x double>, <2 x double>* %p, align 4
469+
ret <2 x double> %v
470+
}
471+
472+
; 2 is the default alignment for v128 so no attribute is needed.
473+
474+
; CHECK-LABEL: load_v2f64_a16:
475+
; CHECK-NEXT: .param i32{{$}}
476+
; CHECK-NEXT: .result v128{{$}}
477+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
478+
; CHECK-NEXT: return $pop[[R]]{{$}}
479+
define <2 x double> @load_v2f64_a16(<2 x double> *%p) {
480+
%v = load <2 x double>, <2 x double>* %p, align 16
481+
ret <2 x double> %v
482+
}
483+
484+
; 32 is greater than the default alignment so it is ignored.
485+
486+
; CHECK-LABEL: load_v2f64_a32:
487+
; CHECK-NEXT: .param i32{{$}}
488+
; CHECK-NEXT: .result v128{{$}}
489+
; CHECK-NEXT: v128.load $push[[R:[0-9]+]]=, 0($0){{$}}
490+
; CHECK-NEXT: return $pop[[R]]{{$}}
491+
define <2 x double> @load_v2f64_a32(<2 x double> *%p) {
492+
%v = load <2 x double>, <2 x double>* %p, align 32
493+
ret <2 x double> %v
494+
}
495+
496+
; CHECK-LABEL: store_v2f64_a1:
497+
; CHECK-NEXT: .param i32, v128{{$}}
498+
; CHECK-NEXT: v128.store 0($0):p2align=0, $1{{$}}
499+
; CHECK-NEXT: return{{$}}
500+
define void @store_v2f64_a1(<2 x double> *%p, <2 x double> %v) {
501+
store <2 x double> %v, <2 x double>* %p, align 1
502+
ret void
503+
}
504+
505+
; CHECK-LABEL: store_v2f64_a4:
506+
; CHECK-NEXT: .param i32, v128{{$}}
507+
; CHECK-NEXT: v128.store 0($0):p2align=2, $1{{$}}
508+
; CHECK-NEXT: return{{$}}
509+
define void @store_v2f64_a4(<2 x double> *%p, <2 x double> %v) {
510+
store <2 x double> %v, <2 x double>* %p, align 4
511+
ret void
512+
}
513+
514+
; 16 is the default alignment for v128 so no attribute is needed.
515+
516+
; CHECK-LABEL: store_v2f64_a16:
517+
; CHECK-NEXT: .param i32, v128{{$}}
518+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
519+
; CHECK-NEXT: return{{$}}
520+
define void @store_v2f64_a16(<2 x double> *%p, <2 x double> %v) {
521+
store <2 x double> %v, <2 x double>* %p, align 16
522+
ret void
523+
}
524+
525+
; 32 is greater than the default alignment so it is ignored.
526+
527+
; CHECK-LABEL: store_v2f64_a32:
528+
; CHECK-NEXT: .param i32, v128{{$}}
529+
; CHECK-NEXT: v128.store 0($0), $1{{$}}
530+
; CHECK-NEXT: return{{$}}
531+
define void @store_v2f64_a32(<2 x double> *%p, <2 x double> %v) {
532+
store <2 x double> %v, <2 x double>* %p, align 32
533+
ret void
534+
}

‎llvm/test/CodeGen/WebAssembly/simd-offset.ll

+96-96
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.