blob: 472bc7a382d5182998a87af42606bbdfa8501f8b [file] [log] [blame]
Wouter van Oortmerssen8a9cb242018-08-27 15:45:51 +00001; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | 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 Ahnd31bc982018-07-09 20:18:21 +00008;===----------------------------------------------------------------------------
9; Loads
10;===----------------------------------------------------------------------------
Heejin Ahn402b4902018-07-02 21:22:59 +000011
Dan Gohmanbb372242016-01-26 03:39:31 +000012; CHECK-LABEL: ldi64_a1:
13; CHECK-NEXT: .param i32{{$}}
14; CHECK-NEXT: .result i64{{$}}
15; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
16; CHECK-NEXT: return $pop[[NUM]]{{$}}
17define i64 @ldi64_a1(i64 *%p) {
18 %v = load i64, i64* %p, align 1
19 ret i64 %v
20}
21
22; CHECK-LABEL: ldi64_a2:
23; CHECK-NEXT: .param i32{{$}}
24; CHECK-NEXT: .result i64{{$}}
25; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
26; CHECK-NEXT: return $pop[[NUM]]{{$}}
27define i64 @ldi64_a2(i64 *%p) {
28 %v = load i64, i64* %p, align 2
29 ret i64 %v
30}
31
32; CHECK-LABEL: ldi64_a4:
33; CHECK-NEXT: .param i32{{$}}
34; CHECK-NEXT: .result i64{{$}}
35; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=2{{$}}
36; CHECK-NEXT: return $pop[[NUM]]{{$}}
37define i64 @ldi64_a4(i64 *%p) {
38 %v = load i64, i64* %p, align 4
39 ret i64 %v
40}
41
Dan Gohman04e7fb72016-04-21 23:59:48 +000042; 8 is the default alignment for i64 so no attribute is needed.
Dan Gohmanbb372242016-01-26 03:39:31 +000043
44; CHECK-LABEL: ldi64_a8:
45; CHECK-NEXT: .param i32{{$}}
46; CHECK-NEXT: .result i64{{$}}
47; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
48; CHECK-NEXT: return $pop[[NUM]]{{$}}
49define i64 @ldi64_a8(i64 *%p) {
50 %v = load i64, i64* %p, align 8
51 ret i64 %v
52}
53
54; The default alignment in LLVM is the same as the defualt alignment in wasm.
55
56; CHECK-LABEL: ldi64:
57; CHECK-NEXT: .param i32{{$}}
58; CHECK-NEXT: .result i64{{$}}
59; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
60; CHECK-NEXT: return $pop[[NUM]]{{$}}
61define i64 @ldi64(i64 *%p) {
62 %v = load i64, i64* %p
63 ret i64 %v
64}
65
Dan Gohman04e7fb72016-04-21 23:59:48 +000066; 16 is greater than the default alignment so it is ignored.
67
Dan Gohmanbb372242016-01-26 03:39:31 +000068; CHECK-LABEL: ldi64_a16:
69; CHECK-NEXT: .param i32{{$}}
70; CHECK-NEXT: .result i64{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +000071; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +000072; CHECK-NEXT: return $pop[[NUM]]{{$}}
73define i64 @ldi64_a16(i64 *%p) {
74 %v = load i64, i64* %p, align 16
75 ret i64 %v
76}
77
Heejin Ahnd31bc982018-07-09 20:18:21 +000078;===----------------------------------------------------------------------------
79; Extending loads
80;===----------------------------------------------------------------------------
Dan Gohmanbb372242016-01-26 03:39:31 +000081
82; CHECK-LABEL: ldi8_a1:
83; CHECK-NEXT: .param i32{{$}}
84; CHECK-NEXT: .result i64{{$}}
85; CHECK-NEXT: i64.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
86; CHECK-NEXT: return $pop[[NUM]]{{$}}
87define i64 @ldi8_a1(i8 *%p) {
88 %v = load i8, i8* %p, align 1
89 %w = zext i8 %v to i64
90 ret i64 %w
91}
92
93; CHECK-LABEL: ldi8_a2:
94; CHECK-NEXT: .param i32{{$}}
95; CHECK-NEXT: .result i64{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +000096; CHECK-NEXT: i64.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +000097; CHECK-NEXT: return $pop[[NUM]]{{$}}
98define i64 @ldi8_a2(i8 *%p) {
99 %v = load i8, i8* %p, align 2
100 %w = zext i8 %v to i64
101 ret i64 %w
102}
103
104; CHECK-LABEL: ldi16_a1:
105; CHECK-NEXT: .param i32{{$}}
106; CHECK-NEXT: .result i64{{$}}
107; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
108; CHECK-NEXT: return $pop[[NUM]]{{$}}
109define i64 @ldi16_a1(i16 *%p) {
110 %v = load i16, i16* %p, align 1
111 %w = zext i16 %v to i64
112 ret i64 %w
113}
114
115; CHECK-LABEL: ldi16_a2:
116; CHECK-NEXT: .param i32{{$}}
117; CHECK-NEXT: .result i64{{$}}
118; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
119; CHECK-NEXT: return $pop[[NUM]]{{$}}
120define i64 @ldi16_a2(i16 *%p) {
121 %v = load i16, i16* %p, align 2
122 %w = zext i16 %v to i64
123 ret i64 %w
124}
125
126; CHECK-LABEL: ldi16_a4:
127; CHECK-NEXT: .param i32{{$}}
128; CHECK-NEXT: .result i64{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +0000129; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000130; CHECK-NEXT: return $pop[[NUM]]{{$}}
131define i64 @ldi16_a4(i16 *%p) {
132 %v = load i16, i16* %p, align 4
133 %w = zext i16 %v to i64
134 ret i64 %w
135}
136
137; CHECK-LABEL: ldi32_a1:
138; CHECK-NEXT: .param i32{{$}}
139; CHECK-NEXT: .result i64{{$}}
140; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
141; CHECK-NEXT: return $pop[[NUM]]{{$}}
142define i64 @ldi32_a1(i32 *%p) {
143 %v = load i32, i32* %p, align 1
144 %w = zext i32 %v to i64
145 ret i64 %w
146}
147
148; CHECK-LABEL: ldi32_a2:
149; CHECK-NEXT: .param i32{{$}}
150; CHECK-NEXT: .result i64{{$}}
151; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
152; CHECK-NEXT: return $pop[[NUM]]{{$}}
153define i64 @ldi32_a2(i32 *%p) {
154 %v = load i32, i32* %p, align 2
155 %w = zext i32 %v to i64
156 ret i64 %w
157}
158
159; CHECK-LABEL: ldi32_a4:
160; CHECK-NEXT: .param i32{{$}}
161; CHECK-NEXT: .result i64{{$}}
162; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
163; CHECK-NEXT: return $pop[[NUM]]{{$}}
164define i64 @ldi32_a4(i32 *%p) {
165 %v = load i32, i32* %p, align 4
166 %w = zext i32 %v to i64
167 ret i64 %w
168}
169
170; CHECK-LABEL: ldi32_a8:
171; CHECK-NEXT: .param i32{{$}}
172; CHECK-NEXT: .result i64{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +0000173; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000174; CHECK-NEXT: return $pop[[NUM]]{{$}}
175define i64 @ldi32_a8(i32 *%p) {
176 %v = load i32, i32* %p, align 8
177 %w = zext i32 %v to i64
178 ret i64 %w
179}
180
Heejin Ahnd31bc982018-07-09 20:18:21 +0000181;===----------------------------------------------------------------------------
182; Stores
183;===----------------------------------------------------------------------------
Dan Gohmanbb372242016-01-26 03:39:31 +0000184
185; CHECK-LABEL: sti64_a1:
186; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000187; CHECK-NEXT: i64.store 0($0):p2align=0, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000188; CHECK-NEXT: return{{$}}
189define void @sti64_a1(i64 *%p, i64 %v) {
190 store i64 %v, i64* %p, align 1
191 ret void
192}
193
194; CHECK-LABEL: sti64_a2:
195; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000196; CHECK-NEXT: i64.store 0($0):p2align=1, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000197; CHECK-NEXT: return{{$}}
198define void @sti64_a2(i64 *%p, i64 %v) {
199 store i64 %v, i64* %p, align 2
200 ret void
201}
202
203; CHECK-LABEL: sti64_a4:
204; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000205; CHECK-NEXT: i64.store 0($0):p2align=2, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000206; CHECK-NEXT: return{{$}}
207define void @sti64_a4(i64 *%p, i64 %v) {
208 store i64 %v, i64* %p, align 4
209 ret void
210}
211
212; 8 is the default alignment for i32 so no attribute is needed.
213
214; CHECK-LABEL: sti64_a8:
215; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000216; CHECK-NEXT: i64.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000217; CHECK-NEXT: return{{$}}
218define void @sti64_a8(i64 *%p, i64 %v) {
219 store i64 %v, i64* %p, align 8
220 ret void
221}
222
223; The default alignment in LLVM is the same as the defualt alignment in wasm.
224
225; CHECK-LABEL: sti64:
226; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000227; CHECK-NEXT: i64.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000228; CHECK-NEXT: return{{$}}
229define void @sti64(i64 *%p, i64 %v) {
230 store i64 %v, i64* %p
231 ret void
232}
233
234; CHECK-LABEL: sti64_a16:
235; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000236; CHECK-NEXT: i64.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000237; CHECK-NEXT: return{{$}}
238define void @sti64_a16(i64 *%p, i64 %v) {
239 store i64 %v, i64* %p, align 16
240 ret void
241}
242
Heejin Ahnd31bc982018-07-09 20:18:21 +0000243;===----------------------------------------------------------------------------
244; Truncating stores
245;===----------------------------------------------------------------------------
Dan Gohmanbb372242016-01-26 03:39:31 +0000246
247; CHECK-LABEL: sti8_a1:
248; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000249; CHECK-NEXT: i64.store8 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000250; CHECK-NEXT: return{{$}}
251define void @sti8_a1(i8 *%p, i64 %w) {
252 %v = trunc i64 %w to i8
253 store i8 %v, i8* %p, align 1
254 ret void
255}
256
257; CHECK-LABEL: sti8_a2:
258; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000259; CHECK-NEXT: i64.store8 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000260; CHECK-NEXT: return{{$}}
261define void @sti8_a2(i8 *%p, i64 %w) {
262 %v = trunc i64 %w to i8
263 store i8 %v, i8* %p, align 2
264 ret void
265}
266
267; CHECK-LABEL: sti16_a1:
268; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000269; CHECK-NEXT: i64.store16 0($0):p2align=0, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000270; CHECK-NEXT: return{{$}}
271define void @sti16_a1(i16 *%p, i64 %w) {
272 %v = trunc i64 %w to i16
273 store i16 %v, i16* %p, align 1
274 ret void
275}
276
277; CHECK-LABEL: sti16_a2:
278; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000279; CHECK-NEXT: i64.store16 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000280; CHECK-NEXT: return{{$}}
281define void @sti16_a2(i16 *%p, i64 %w) {
282 %v = trunc i64 %w to i16
283 store i16 %v, i16* %p, align 2
284 ret void
285}
286
287; CHECK-LABEL: sti16_a4:
288; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000289; CHECK-NEXT: i64.store16 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000290; CHECK-NEXT: return{{$}}
291define void @sti16_a4(i16 *%p, i64 %w) {
292 %v = trunc i64 %w to i16
293 store i16 %v, i16* %p, align 4
294 ret void
295}
296
297; CHECK-LABEL: sti32_a1:
298; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000299; CHECK-NEXT: i64.store32 0($0):p2align=0, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000300; CHECK-NEXT: return{{$}}
301define void @sti32_a1(i32 *%p, i64 %w) {
302 %v = trunc i64 %w to i32
303 store i32 %v, i32* %p, align 1
304 ret void
305}
306
307; CHECK-LABEL: sti32_a2:
308; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000309; CHECK-NEXT: i64.store32 0($0):p2align=1, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000310; CHECK-NEXT: return{{$}}
311define void @sti32_a2(i32 *%p, i64 %w) {
312 %v = trunc i64 %w to i32
313 store i32 %v, i32* %p, align 2
314 ret void
315}
316
317; CHECK-LABEL: sti32_a4:
318; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000319; CHECK-NEXT: i64.store32 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000320; CHECK-NEXT: return{{$}}
321define void @sti32_a4(i32 *%p, i64 %w) {
322 %v = trunc i64 %w to i32
323 store i32 %v, i32* %p, align 4
324 ret void
325}
326
327; CHECK-LABEL: sti32_a8:
328; CHECK-NEXT: .param i32, i64{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000329; CHECK-NEXT: i64.store32 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000330; CHECK-NEXT: return{{$}}
331define void @sti32_a8(i32 *%p, i64 %w) {
332 %v = trunc i64 %w to i32
333 store i32 %v, i32* %p, align 8
334 ret void
335}
Derek Schuff885dc592017-10-05 21:18:42 +0000336
Heejin Ahnd31bc982018-07-09 20:18:21 +0000337;===----------------------------------------------------------------------------
338; Atomic loads
339;===----------------------------------------------------------------------------
340
Heejin Ahn402b4902018-07-02 21:22:59 +0000341; Wasm atomics have the alignment field, but it must always have the type's
342; natural alignment.
343
Derek Schuff885dc592017-10-05 21:18:42 +0000344; CHECK-LABEL: ldi64_atomic_a8:
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_a8(i64 *%p) {
350 %v = load atomic i64, i64* %p seq_cst, align 8
351 ret i64 %v
352}
353
354; 16 is greater than the default alignment so it is ignored.
Heejin Ahnd31bc982018-07-09 20:18:21 +0000355
Derek Schuff885dc592017-10-05 21:18:42 +0000356; CHECK-LABEL: ldi64_atomic_a16:
357; CHECK-NEXT: .param i32{{$}}
358; CHECK-NEXT: .result i64{{$}}
359; CHECK-NEXT: i64.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
360; CHECK-NEXT: return $pop[[NUM]]{{$}}
361define i64 @ldi64_atomic_a16(i64 *%p) {
362 %v = load atomic i64, i64* %p seq_cst, align 16
363 ret i64 %v
364}
Heejin Ahn402b4902018-07-02 21:22:59 +0000365
Heejin Ahnd31bc982018-07-09 20:18:21 +0000366;===----------------------------------------------------------------------------
367; Atomic stores
368;===----------------------------------------------------------------------------
369
Heejin Ahn402b4902018-07-02 21:22:59 +0000370; CHECK-LABEL: sti64_atomic_a4:
371; CHECK-NEXT: .param i32, i64{{$}}
372; CHECK-NEXT: i64.atomic.store 0($0), $1{{$}}
373; CHECK-NEXT: return{{$}}
374define void @sti64_atomic_a4(i64 *%p, i64 %v) {
375 store atomic i64 %v, i64* %p seq_cst, align 8
376 ret void
377}
378
379; 16 is greater than the default alignment so it is ignored.
Heejin Ahnd31bc982018-07-09 20:18:21 +0000380
Heejin Ahn402b4902018-07-02 21:22:59 +0000381; CHECK-LABEL: sti64_atomic_a8:
382; CHECK-NEXT: .param i32, i64{{$}}
383; CHECK-NEXT: i64.atomic.store 0($0), $1{{$}}
384; CHECK-NEXT: return{{$}}
385define void @sti64_atomic_a8(i64 *%p, i64 %v) {
386 store atomic i64 %v, i64* %p seq_cst, align 16
387 ret void
388}