blob: 3290b9c73763847a2898770c1ac74462b0c0be1b [file] [log] [blame]
Dan Gohmanbb372242016-01-26 03:39:31 +00001; RUN: llc < %s -asm-verbose=false | FileCheck %s
2
3; Test loads and stores with custom alignment values.
4
5target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
6target triple = "wasm32-unknown-unknown"
7
8; CHECK-LABEL: ldi64_a1:
9; CHECK-NEXT: .param i32{{$}}
10; CHECK-NEXT: .result i64{{$}}
11; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
12; CHECK-NEXT: return $pop[[NUM]]{{$}}
13define i64 @ldi64_a1(i64 *%p) {
14 %v = load i64, i64* %p, align 1
15 ret i64 %v
16}
17
18; CHECK-LABEL: ldi64_a2:
19; CHECK-NEXT: .param i32{{$}}
20; CHECK-NEXT: .result i64{{$}}
21; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
22; CHECK-NEXT: return $pop[[NUM]]{{$}}
23define i64 @ldi64_a2(i64 *%p) {
24 %v = load i64, i64* %p, align 2
25 ret i64 %v
26}
27
28; CHECK-LABEL: ldi64_a4:
29; CHECK-NEXT: .param i32{{$}}
30; CHECK-NEXT: .result i64{{$}}
31; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=2{{$}}
32; CHECK-NEXT: return $pop[[NUM]]{{$}}
33define i64 @ldi64_a4(i64 *%p) {
34 %v = load i64, i64* %p, align 4
35 ret i64 %v
36}
37
38; 8 is the default alignment for i32 so no attribute is needed.
39
40; CHECK-LABEL: ldi64_a8:
41; CHECK-NEXT: .param i32{{$}}
42; CHECK-NEXT: .result i64{{$}}
43; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
44; CHECK-NEXT: return $pop[[NUM]]{{$}}
45define i64 @ldi64_a8(i64 *%p) {
46 %v = load i64, i64* %p, align 8
47 ret i64 %v
48}
49
50; The default alignment in LLVM is the same as the defualt alignment in wasm.
51
52; CHECK-LABEL: ldi64:
53; CHECK-NEXT: .param i32{{$}}
54; CHECK-NEXT: .result i64{{$}}
55; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
56; CHECK-NEXT: return $pop[[NUM]]{{$}}
57define i64 @ldi64(i64 *%p) {
58 %v = load i64, i64* %p
59 ret i64 %v
60}
61
62; CHECK-LABEL: ldi64_a16:
63; CHECK-NEXT: .param i32{{$}}
64; CHECK-NEXT: .result i64{{$}}
65; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=4{{$}}
66; CHECK-NEXT: return $pop[[NUM]]{{$}}
67define i64 @ldi64_a16(i64 *%p) {
68 %v = load i64, i64* %p, align 16
69 ret i64 %v
70}
71
72; Extending loads.
73
74; CHECK-LABEL: ldi8_a1:
75; CHECK-NEXT: .param i32{{$}}
76; CHECK-NEXT: .result i64{{$}}
77; CHECK-NEXT: i64.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
78; CHECK-NEXT: return $pop[[NUM]]{{$}}
79define i64 @ldi8_a1(i8 *%p) {
80 %v = load i8, i8* %p, align 1
81 %w = zext i8 %v to i64
82 ret i64 %w
83}
84
85; CHECK-LABEL: ldi8_a2:
86; CHECK-NEXT: .param i32{{$}}
87; CHECK-NEXT: .result i64{{$}}
88; CHECK-NEXT: i64.load8_u $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
89; CHECK-NEXT: return $pop[[NUM]]{{$}}
90define i64 @ldi8_a2(i8 *%p) {
91 %v = load i8, i8* %p, align 2
92 %w = zext i8 %v to i64
93 ret i64 %w
94}
95
96; CHECK-LABEL: ldi16_a1:
97; CHECK-NEXT: .param i32{{$}}
98; CHECK-NEXT: .result i64{{$}}
99; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
100; CHECK-NEXT: return $pop[[NUM]]{{$}}
101define i64 @ldi16_a1(i16 *%p) {
102 %v = load i16, i16* %p, align 1
103 %w = zext i16 %v to i64
104 ret i64 %w
105}
106
107; CHECK-LABEL: ldi16_a2:
108; CHECK-NEXT: .param i32{{$}}
109; CHECK-NEXT: .result i64{{$}}
110; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
111; CHECK-NEXT: return $pop[[NUM]]{{$}}
112define i64 @ldi16_a2(i16 *%p) {
113 %v = load i16, i16* %p, align 2
114 %w = zext i16 %v to i64
115 ret i64 %w
116}
117
118; CHECK-LABEL: ldi16_a4:
119; CHECK-NEXT: .param i32{{$}}
120; CHECK-NEXT: .result i64{{$}}
121; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=2{{$}}
122; CHECK-NEXT: return $pop[[NUM]]{{$}}
123define i64 @ldi16_a4(i16 *%p) {
124 %v = load i16, i16* %p, align 4
125 %w = zext i16 %v to i64
126 ret i64 %w
127}
128
129; CHECK-LABEL: ldi32_a1:
130; CHECK-NEXT: .param i32{{$}}
131; CHECK-NEXT: .result i64{{$}}
132; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
133; CHECK-NEXT: return $pop[[NUM]]{{$}}
134define i64 @ldi32_a1(i32 *%p) {
135 %v = load i32, i32* %p, align 1
136 %w = zext i32 %v to i64
137 ret i64 %w
138}
139
140; CHECK-LABEL: ldi32_a2:
141; CHECK-NEXT: .param i32{{$}}
142; CHECK-NEXT: .result i64{{$}}
143; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
144; CHECK-NEXT: return $pop[[NUM]]{{$}}
145define i64 @ldi32_a2(i32 *%p) {
146 %v = load i32, i32* %p, align 2
147 %w = zext i32 %v to i64
148 ret i64 %w
149}
150
151; CHECK-LABEL: ldi32_a4:
152; CHECK-NEXT: .param i32{{$}}
153; CHECK-NEXT: .result i64{{$}}
154; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
155; CHECK-NEXT: return $pop[[NUM]]{{$}}
156define i64 @ldi32_a4(i32 *%p) {
157 %v = load i32, i32* %p, align 4
158 %w = zext i32 %v to i64
159 ret i64 %w
160}
161
162; CHECK-LABEL: ldi32_a8:
163; CHECK-NEXT: .param i32{{$}}
164; CHECK-NEXT: .result i64{{$}}
165; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0):p2align=3{{$}}
166; CHECK-NEXT: return $pop[[NUM]]{{$}}
167define i64 @ldi32_a8(i32 *%p) {
168 %v = load i32, i32* %p, align 8
169 %w = zext i32 %v to i64
170 ret i64 %w
171}
172
173; Stores.
174
175; CHECK-LABEL: sti64_a1:
176; CHECK-NEXT: .param i32, i64{{$}}
177; CHECK-NEXT: i64.store $discard=, 0($0):p2align=0, $1{{$}}
178; CHECK-NEXT: return{{$}}
179define void @sti64_a1(i64 *%p, i64 %v) {
180 store i64 %v, i64* %p, align 1
181 ret void
182}
183
184; CHECK-LABEL: sti64_a2:
185; CHECK-NEXT: .param i32, i64{{$}}
186; CHECK-NEXT: i64.store $discard=, 0($0):p2align=1, $1{{$}}
187; CHECK-NEXT: return{{$}}
188define void @sti64_a2(i64 *%p, i64 %v) {
189 store i64 %v, i64* %p, align 2
190 ret void
191}
192
193; CHECK-LABEL: sti64_a4:
194; CHECK-NEXT: .param i32, i64{{$}}
195; CHECK-NEXT: i64.store $discard=, 0($0):p2align=2, $1{{$}}
196; CHECK-NEXT: return{{$}}
197define void @sti64_a4(i64 *%p, i64 %v) {
198 store i64 %v, i64* %p, align 4
199 ret void
200}
201
202; 8 is the default alignment for i32 so no attribute is needed.
203
204; CHECK-LABEL: sti64_a8:
205; CHECK-NEXT: .param i32, i64{{$}}
206; CHECK-NEXT: i64.store $discard=, 0($0), $1{{$}}
207; CHECK-NEXT: return{{$}}
208define void @sti64_a8(i64 *%p, i64 %v) {
209 store i64 %v, i64* %p, align 8
210 ret void
211}
212
213; The default alignment in LLVM is the same as the defualt alignment in wasm.
214
215; CHECK-LABEL: sti64:
216; CHECK-NEXT: .param i32, i64{{$}}
217; CHECK-NEXT: i64.store $discard=, 0($0), $1{{$}}
218; CHECK-NEXT: return{{$}}
219define void @sti64(i64 *%p, i64 %v) {
220 store i64 %v, i64* %p
221 ret void
222}
223
224; CHECK-LABEL: sti64_a16:
225; CHECK-NEXT: .param i32, i64{{$}}
226; CHECK-NEXT: i64.store $discard=, 0($0):p2align=4, $1{{$}}
227; CHECK-NEXT: return{{$}}
228define void @sti64_a16(i64 *%p, i64 %v) {
229 store i64 %v, i64* %p, align 16
230 ret void
231}
232
233; Truncating stores.
234
235; CHECK-LABEL: sti8_a1:
236; CHECK-NEXT: .param i32, i64{{$}}
237; CHECK-NEXT: i64.store8 $discard=, 0($0), $1{{$}}
238; CHECK-NEXT: return{{$}}
239define void @sti8_a1(i8 *%p, i64 %w) {
240 %v = trunc i64 %w to i8
241 store i8 %v, i8* %p, align 1
242 ret void
243}
244
245; CHECK-LABEL: sti8_a2:
246; CHECK-NEXT: .param i32, i64{{$}}
247; CHECK-NEXT: i64.store8 $discard=, 0($0):p2align=1, $1{{$}}
248; CHECK-NEXT: return{{$}}
249define void @sti8_a2(i8 *%p, i64 %w) {
250 %v = trunc i64 %w to i8
251 store i8 %v, i8* %p, align 2
252 ret void
253}
254
255; CHECK-LABEL: sti16_a1:
256; CHECK-NEXT: .param i32, i64{{$}}
257; CHECK-NEXT: i64.store16 $discard=, 0($0):p2align=0, $1{{$}}
258; CHECK-NEXT: return{{$}}
259define void @sti16_a1(i16 *%p, i64 %w) {
260 %v = trunc i64 %w to i16
261 store i16 %v, i16* %p, align 1
262 ret void
263}
264
265; CHECK-LABEL: sti16_a2:
266; CHECK-NEXT: .param i32, i64{{$}}
267; CHECK-NEXT: i64.store16 $discard=, 0($0), $1{{$}}
268; CHECK-NEXT: return{{$}}
269define void @sti16_a2(i16 *%p, i64 %w) {
270 %v = trunc i64 %w to i16
271 store i16 %v, i16* %p, align 2
272 ret void
273}
274
275; CHECK-LABEL: sti16_a4:
276; CHECK-NEXT: .param i32, i64{{$}}
277; CHECK-NEXT: i64.store16 $discard=, 0($0):p2align=2, $1{{$}}
278; CHECK-NEXT: return{{$}}
279define void @sti16_a4(i16 *%p, i64 %w) {
280 %v = trunc i64 %w to i16
281 store i16 %v, i16* %p, align 4
282 ret void
283}
284
285; CHECK-LABEL: sti32_a1:
286; CHECK-NEXT: .param i32, i64{{$}}
287; CHECK-NEXT: i64.store32 $discard=, 0($0):p2align=0, $1{{$}}
288; CHECK-NEXT: return{{$}}
289define void @sti32_a1(i32 *%p, i64 %w) {
290 %v = trunc i64 %w to i32
291 store i32 %v, i32* %p, align 1
292 ret void
293}
294
295; CHECK-LABEL: sti32_a2:
296; CHECK-NEXT: .param i32, i64{{$}}
297; CHECK-NEXT: i64.store32 $discard=, 0($0):p2align=1, $1{{$}}
298; CHECK-NEXT: return{{$}}
299define void @sti32_a2(i32 *%p, i64 %w) {
300 %v = trunc i64 %w to i32
301 store i32 %v, i32* %p, align 2
302 ret void
303}
304
305; CHECK-LABEL: sti32_a4:
306; CHECK-NEXT: .param i32, i64{{$}}
307; CHECK-NEXT: i64.store32 $discard=, 0($0), $1{{$}}
308; CHECK-NEXT: return{{$}}
309define void @sti32_a4(i32 *%p, i64 %w) {
310 %v = trunc i64 %w to i32
311 store i32 %v, i32* %p, align 4
312 ret void
313}
314
315; CHECK-LABEL: sti32_a8:
316; CHECK-NEXT: .param i32, i64{{$}}
317; CHECK-NEXT: i64.store32 $discard=, 0($0):p2align=3, $1{{$}}
318; CHECK-NEXT: return{{$}}
319define void @sti32_a8(i32 *%p, i64 %w) {
320 %v = trunc i64 %w to i32
321 store i32 %v, i32* %p, align 8
322 ret void
323}