blob: f3b8e15b6027ff3642173c8d3584f5b3708459e9 [file] [log] [blame]
Derek Schuff885dc592017-10-05 21:18:42 +00001; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
Dan Gohmanbb372242016-01-26 03:39:31 +00002
3; Test loads and stores with custom alignment values.
4
5target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
Sam Clegga5908002018-05-10 17:49:11 +00006target triple = "wasm32-unknown-unknown"
Dan Gohmanbb372242016-01-26 03:39:31 +00007
Heejin Ahn402b4902018-07-02 21:22:59 +00008; Loads.
9
Dan Gohmanbb372242016-01-26 03:39:31 +000010; CHECK-LABEL: ldi64_a1:
11; CHECK-NEXT: .param i32{{$}}
12; CHECK-NEXT: .result i64{{$}}
13; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
14; CHECK-NEXT: return $pop[[NUM]]{{$}}
15define i64 @ldi64_a1(i64 *%p) {
16 %v = load i64, i64* %p, align 1
17 ret i64 %v
18}
19
20; CHECK-LABEL: ldi64_a2:
21; CHECK-NEXT: .param i32{{$}}
22; CHECK-NEXT: .result i64{{$}}
23; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
24; CHECK-NEXT: return $pop[[NUM]]{{$}}
25define i64 @ldi64_a2(i64 *%p) {
26 %v = load i64, i64* %p, align 2
27 ret i64 %v
28}
29
30; CHECK-LABEL: ldi64_a4:
31; CHECK-NEXT: .param i32{{$}}
32; CHECK-NEXT: .result i64{{$}}
33; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=2{{$}}
34; CHECK-NEXT: return $pop[[NUM]]{{$}}
35define i64 @ldi64_a4(i64 *%p) {
36 %v = load i64, i64* %p, align 4
37 ret i64 %v
38}
39
Dan Gohman04e7fb72016-04-21 23:59:48 +000040; 8 is the default alignment for i64 so no attribute is needed.
Dan Gohmanbb372242016-01-26 03:39:31 +000041
42; CHECK-LABEL: ldi64_a8:
43; CHECK-NEXT: .param i32{{$}}
44; CHECK-NEXT: .result i64{{$}}
45; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
46; CHECK-NEXT: return $pop[[NUM]]{{$}}
47define i64 @ldi64_a8(i64 *%p) {
48 %v = load i64, i64* %p, align 8
49 ret i64 %v
50}
51
52; The default alignment in LLVM is the same as the defualt alignment in wasm.
53
54; CHECK-LABEL: ldi64:
55; CHECK-NEXT: .param i32{{$}}
56; CHECK-NEXT: .result i64{{$}}
57; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
58; CHECK-NEXT: return $pop[[NUM]]{{$}}
59define i64 @ldi64(i64 *%p) {
60 %v = load i64, i64* %p
61 ret i64 %v
62}
63
Dan Gohman04e7fb72016-04-21 23:59:48 +000064; 16 is greater than the default alignment so it is ignored.
65
Dan Gohmanbb372242016-01-26 03:39:31 +000066; CHECK-LABEL: ldi64_a16:
67; CHECK-NEXT: .param i32{{$}}
68; CHECK-NEXT: .result i64{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +000069; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +000070; CHECK-NEXT: return $pop[[NUM]]{{$}}
71define i64 @ldi64_a16(i64 *%p) {
72 %v = load i64, i64* %p, align 16
73 ret i64 %v
74}
75
76; Extending loads.
77
78; CHECK-LABEL: ldi8_a1:
79; CHECK-NEXT: .param i32{{$}}
80; CHECK-NEXT: .result i64{{$}}
81; CHECK-NEXT: i64.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
82; CHECK-NEXT: return $pop[[NUM]]{{$}}
83define i64 @ldi8_a1(i8 *%p) {
84 %v = load i8, i8* %p, align 1
85 %w = zext i8 %v to i64
86 ret i64 %w
87}
88
89; CHECK-LABEL: ldi8_a2:
90; CHECK-NEXT: .param i32{{$}}
91; CHECK-NEXT: .result i64{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +000092; CHECK-NEXT: i64.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +000093; CHECK-NEXT: return $pop[[NUM]]{{$}}
94define i64 @ldi8_a2(i8 *%p) {
95 %v = load i8, i8* %p, align 2
96 %w = zext i8 %v to i64
97 ret i64 %w
98}
99
100; CHECK-LABEL: ldi16_a1:
101; CHECK-NEXT: .param i32{{$}}
102; CHECK-NEXT: .result i64{{$}}
103; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
104; CHECK-NEXT: return $pop[[NUM]]{{$}}
105define i64 @ldi16_a1(i16 *%p) {
106 %v = load i16, i16* %p, align 1
107 %w = zext i16 %v to i64
108 ret i64 %w
109}
110
111; CHECK-LABEL: ldi16_a2:
112; CHECK-NEXT: .param i32{{$}}
113; CHECK-NEXT: .result i64{{$}}
114; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
115; CHECK-NEXT: return $pop[[NUM]]{{$}}
116define i64 @ldi16_a2(i16 *%p) {
117 %v = load i16, i16* %p, align 2
118 %w = zext i16 %v to i64
119 ret i64 %w
120}
121
122; CHECK-LABEL: ldi16_a4:
123; CHECK-NEXT: .param i32{{$}}
124; CHECK-NEXT: .result i64{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +0000125; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000126; CHECK-NEXT: return $pop[[NUM]]{{$}}
127define i64 @ldi16_a4(i16 *%p) {
128 %v = load i16, i16* %p, align 4
129 %w = zext i16 %v to i64
130 ret i64 %w
131}
132
133; CHECK-LABEL: ldi32_a1:
134; CHECK-NEXT: .param i32{{$}}
135; CHECK-NEXT: .result i64{{$}}
136; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
137; CHECK-NEXT: return $pop[[NUM]]{{$}}
138define i64 @ldi32_a1(i32 *%p) {
139 %v = load i32, i32* %p, align 1
140 %w = zext i32 %v to i64
141 ret i64 %w
142}
143
144; CHECK-LABEL: ldi32_a2:
145; CHECK-NEXT: .param i32{{$}}
146; CHECK-NEXT: .result i64{{$}}
147; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
148; CHECK-NEXT: return $pop[[NUM]]{{$}}
149define i64 @ldi32_a2(i32 *%p) {
150 %v = load i32, i32* %p, align 2
151 %w = zext i32 %v to i64
152 ret i64 %w
153}
154
155; CHECK-LABEL: ldi32_a4:
156; CHECK-NEXT: .param i32{{$}}
157; CHECK-NEXT: .result i64{{$}}
158; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
159; CHECK-NEXT: return $pop[[NUM]]{{$}}
160define i64 @ldi32_a4(i32 *%p) {
161 %v = load i32, i32* %p, align 4
162 %w = zext i32 %v to i64
163 ret i64 %w
164}
165
166; CHECK-LABEL: ldi32_a8:
167; CHECK-NEXT: .param i32{{$}}
168; CHECK-NEXT: .result i64{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +0000169; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000170; CHECK-NEXT: return $pop[[NUM]]{{$}}
171define i64 @ldi32_a8(i32 *%p) {
172 %v = load i32, i32* %p, align 8
173 %w = zext i32 %v to i64
174 ret i64 %w
175}
176
177; Stores.
178
179; CHECK-LABEL: sti64_a1:
180; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000181; CHECK-NEXT: i64.store 0($0):p2align=0, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000182; CHECK-NEXT: return{{$}}
183define void @sti64_a1(i64 *%p, i64 %v) {
184 store i64 %v, i64* %p, align 1
185 ret void
186}
187
188; CHECK-LABEL: sti64_a2:
189; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000190; CHECK-NEXT: i64.store 0($0):p2align=1, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000191; CHECK-NEXT: return{{$}}
192define void @sti64_a2(i64 *%p, i64 %v) {
193 store i64 %v, i64* %p, align 2
194 ret void
195}
196
197; CHECK-LABEL: sti64_a4:
198; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000199; CHECK-NEXT: i64.store 0($0):p2align=2, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000200; CHECK-NEXT: return{{$}}
201define void @sti64_a4(i64 *%p, i64 %v) {
202 store i64 %v, i64* %p, align 4
203 ret void
204}
205
206; 8 is the default alignment for i32 so no attribute is needed.
207
208; CHECK-LABEL: sti64_a8:
209; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000210; CHECK-NEXT: i64.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000211; CHECK-NEXT: return{{$}}
212define void @sti64_a8(i64 *%p, i64 %v) {
213 store i64 %v, i64* %p, align 8
214 ret void
215}
216
217; The default alignment in LLVM is the same as the defualt alignment in wasm.
218
219; CHECK-LABEL: sti64:
220; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000221; CHECK-NEXT: i64.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000222; CHECK-NEXT: return{{$}}
223define void @sti64(i64 *%p, i64 %v) {
224 store i64 %v, i64* %p
225 ret void
226}
227
228; CHECK-LABEL: sti64_a16:
229; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000230; CHECK-NEXT: i64.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000231; CHECK-NEXT: return{{$}}
232define void @sti64_a16(i64 *%p, i64 %v) {
233 store i64 %v, i64* %p, align 16
234 ret void
235}
236
237; Truncating stores.
238
239; CHECK-LABEL: sti8_a1:
240; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000241; CHECK-NEXT: i64.store8 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000242; CHECK-NEXT: return{{$}}
243define void @sti8_a1(i8 *%p, i64 %w) {
244 %v = trunc i64 %w to i8
245 store i8 %v, i8* %p, align 1
246 ret void
247}
248
249; CHECK-LABEL: sti8_a2:
250; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000251; CHECK-NEXT: i64.store8 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000252; CHECK-NEXT: return{{$}}
253define void @sti8_a2(i8 *%p, i64 %w) {
254 %v = trunc i64 %w to i8
255 store i8 %v, i8* %p, align 2
256 ret void
257}
258
259; CHECK-LABEL: sti16_a1:
260; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000261; CHECK-NEXT: i64.store16 0($0):p2align=0, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000262; CHECK-NEXT: return{{$}}
263define void @sti16_a1(i16 *%p, i64 %w) {
264 %v = trunc i64 %w to i16
265 store i16 %v, i16* %p, align 1
266 ret void
267}
268
269; CHECK-LABEL: sti16_a2:
270; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000271; CHECK-NEXT: i64.store16 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000272; CHECK-NEXT: return{{$}}
273define void @sti16_a2(i16 *%p, i64 %w) {
274 %v = trunc i64 %w to i16
275 store i16 %v, i16* %p, align 2
276 ret void
277}
278
279; CHECK-LABEL: sti16_a4:
280; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000281; CHECK-NEXT: i64.store16 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000282; CHECK-NEXT: return{{$}}
283define void @sti16_a4(i16 *%p, i64 %w) {
284 %v = trunc i64 %w to i16
285 store i16 %v, i16* %p, align 4
286 ret void
287}
288
289; CHECK-LABEL: sti32_a1:
290; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000291; CHECK-NEXT: i64.store32 0($0):p2align=0, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000292; CHECK-NEXT: return{{$}}
293define void @sti32_a1(i32 *%p, i64 %w) {
294 %v = trunc i64 %w to i32
295 store i32 %v, i32* %p, align 1
296 ret void
297}
298
299; CHECK-LABEL: sti32_a2:
300; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000301; CHECK-NEXT: i64.store32 0($0):p2align=1, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000302; CHECK-NEXT: return{{$}}
303define void @sti32_a2(i32 *%p, i64 %w) {
304 %v = trunc i64 %w to i32
305 store i32 %v, i32* %p, align 2
306 ret void
307}
308
309; CHECK-LABEL: sti32_a4:
310; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000311; CHECK-NEXT: i64.store32 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000312; CHECK-NEXT: return{{$}}
313define void @sti32_a4(i32 *%p, i64 %w) {
314 %v = trunc i64 %w to i32
315 store i32 %v, i32* %p, align 4
316 ret void
317}
318
319; CHECK-LABEL: sti32_a8:
320; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000321; CHECK-NEXT: i64.store32 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000322; CHECK-NEXT: return{{$}}
323define void @sti32_a8(i32 *%p, i64 %w) {
324 %v = trunc i64 %w to i32
325 store i32 %v, i32* %p, align 8
326 ret void
327}
Derek Schuff885dc592017-10-05 21:18:42 +0000328
329; Atomics.
Heejin Ahn402b4902018-07-02 21:22:59 +0000330; Wasm atomics have the alignment field, but it must always have the type's
331; natural alignment.
332
Derek Schuff885dc592017-10-05 21:18:42 +0000333; CHECK-LABEL: ldi64_atomic_a8:
334; CHECK-NEXT: .param i32{{$}}
335; CHECK-NEXT: .result i64{{$}}
336; CHECK-NEXT: i64.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
337; CHECK-NEXT: return $pop[[NUM]]{{$}}
338define i64 @ldi64_atomic_a8(i64 *%p) {
339 %v = load atomic i64, i64* %p seq_cst, align 8
340 ret i64 %v
341}
342
343; 16 is greater than the default alignment so it is ignored.
Derek Schuff885dc592017-10-05 21:18:42 +0000344; CHECK-LABEL: ldi64_atomic_a16:
345; CHECK-NEXT: .param i32{{$}}
346; CHECK-NEXT: .result i64{{$}}
347; CHECK-NEXT: i64.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
348; CHECK-NEXT: return $pop[[NUM]]{{$}}
349define i64 @ldi64_atomic_a16(i64 *%p) {
350 %v = load atomic i64, i64* %p seq_cst, align 16
351 ret i64 %v
352}
Heejin Ahn402b4902018-07-02 21:22:59 +0000353
354; CHECK-LABEL: sti64_atomic_a4:
355; CHECK-NEXT: .param i32, i64{{$}}
356; CHECK-NEXT: i64.atomic.store 0($0), $1{{$}}
357; CHECK-NEXT: return{{$}}
358define void @sti64_atomic_a4(i64 *%p, i64 %v) {
359 store atomic i64 %v, i64* %p seq_cst, align 8
360 ret void
361}
362
363; 16 is greater than the default alignment so it is ignored.
364; CHECK-LABEL: sti64_atomic_a8:
365; CHECK-NEXT: .param i32, i64{{$}}
366; CHECK-NEXT: i64.atomic.store 0($0), $1{{$}}
367; CHECK-NEXT: return{{$}}
368define void @sti64_atomic_a8(i64 *%p, i64 %v) {
369 store atomic i64 %v, i64* %p seq_cst, align 16
370 ret void
371}