blob: 1296632cca3a26fa0e855a9da336d22d17a53746 [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"
Dan Gohman7d7409e2017-02-28 23:37:04 +00006target triple = "wasm32-unknown-unknown-wasm"
Dan Gohmanbb372242016-01-26 03:39:31 +00007
8; CHECK-LABEL: ldi32_a1:
9; CHECK-NEXT: .param i32{{$}}
10; CHECK-NEXT: .result i32{{$}}
11; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
12; CHECK-NEXT: return $pop[[NUM]]{{$}}
13define i32 @ldi32_a1(i32 *%p) {
14 %v = load i32, i32* %p, align 1
15 ret i32 %v
16}
17
18; CHECK-LABEL: ldi32_a2:
19; CHECK-NEXT: .param i32{{$}}
20; CHECK-NEXT: .result i32{{$}}
21; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
22; CHECK-NEXT: return $pop[[NUM]]{{$}}
23define i32 @ldi32_a2(i32 *%p) {
24 %v = load i32, i32* %p, align 2
25 ret i32 %v
26}
27
28; 4 is the default alignment for i32 so no attribute is needed.
29
30; CHECK-LABEL: ldi32_a4:
31; CHECK-NEXT: .param i32{{$}}
32; CHECK-NEXT: .result i32{{$}}
33; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
34; CHECK-NEXT: return $pop[[NUM]]{{$}}
35define i32 @ldi32_a4(i32 *%p) {
36 %v = load i32, i32* %p, align 4
37 ret i32 %v
38}
39
40; The default alignment in LLVM is the same as the defualt alignment in wasm.
41
42; CHECK-LABEL: ldi32:
43; CHECK-NEXT: .param i32{{$}}
44; CHECK-NEXT: .result i32{{$}}
45; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
46; CHECK-NEXT: return $pop[[NUM]]{{$}}
47define i32 @ldi32(i32 *%p) {
48 %v = load i32, i32* %p
49 ret i32 %v
50}
51
Dan Gohman04e7fb72016-04-21 23:59:48 +000052; 8 is greater than the default alignment so it is ignored.
53
Dan Gohmanbb372242016-01-26 03:39:31 +000054; CHECK-LABEL: ldi32_a8:
55; CHECK-NEXT: .param i32{{$}}
56; CHECK-NEXT: .result i32{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +000057; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +000058; CHECK-NEXT: return $pop[[NUM]]{{$}}
59define i32 @ldi32_a8(i32 *%p) {
60 %v = load i32, i32* %p, align 8
61 ret i32 %v
62}
63
64; Extending loads.
65
66; CHECK-LABEL: ldi8_a1:
67; CHECK-NEXT: .param i32{{$}}
68; CHECK-NEXT: .result i32{{$}}
69; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
70; CHECK-NEXT: return $pop[[NUM]]{{$}}
71define i8 @ldi8_a1(i8 *%p) {
72 %v = load i8, i8* %p, align 1
73 ret i8 %v
74}
75
76; CHECK-LABEL: ldi8_a2:
77; CHECK-NEXT: .param i32{{$}}
78; CHECK-NEXT: .result i32{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +000079; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +000080; CHECK-NEXT: return $pop[[NUM]]{{$}}
81define i8 @ldi8_a2(i8 *%p) {
82 %v = load i8, i8* %p, align 2
83 ret i8 %v
84}
85
86; CHECK-LABEL: ldi16_a1:
87; CHECK-NEXT: .param i32{{$}}
88; CHECK-NEXT: .result i32{{$}}
89; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
90; CHECK-NEXT: return $pop[[NUM]]{{$}}
91define i16 @ldi16_a1(i16 *%p) {
92 %v = load i16, i16* %p, align 1
93 ret i16 %v
94}
95
96; CHECK-LABEL: ldi16_a2:
97; CHECK-NEXT: .param i32{{$}}
98; CHECK-NEXT: .result i32{{$}}
99; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
100; CHECK-NEXT: return $pop[[NUM]]{{$}}
101define i16 @ldi16_a2(i16 *%p) {
102 %v = load i16, i16* %p, align 2
103 ret i16 %v
104}
105
106; CHECK-LABEL: ldi16_a4:
107; CHECK-NEXT: .param i32{{$}}
108; CHECK-NEXT: .result i32{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +0000109; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000110; CHECK-NEXT: return $pop[[NUM]]{{$}}
111define i16 @ldi16_a4(i16 *%p) {
112 %v = load i16, i16* %p, align 4
113 ret i16 %v
114}
115
116; Stores.
117
118; CHECK-LABEL: sti32_a1:
119; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000120; CHECK-NEXT: i32.store 0($0):p2align=0, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000121; CHECK-NEXT: return{{$}}
122define void @sti32_a1(i32 *%p, i32 %v) {
123 store i32 %v, i32* %p, align 1
124 ret void
125}
126
127; CHECK-LABEL: sti32_a2:
128; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000129; CHECK-NEXT: i32.store 0($0):p2align=1, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000130; CHECK-NEXT: return{{$}}
131define void @sti32_a2(i32 *%p, i32 %v) {
132 store i32 %v, i32* %p, align 2
133 ret void
134}
135
136; 4 is the default alignment for i32 so no attribute is needed.
137
138; CHECK-LABEL: sti32_a4:
139; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000140; CHECK-NEXT: i32.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000141; CHECK-NEXT: return{{$}}
142define void @sti32_a4(i32 *%p, i32 %v) {
143 store i32 %v, i32* %p, align 4
144 ret void
145}
146
147; The default alignment in LLVM is the same as the defualt alignment in wasm.
148
149; CHECK-LABEL: sti32:
150; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000151; CHECK-NEXT: i32.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000152; CHECK-NEXT: return{{$}}
153define void @sti32(i32 *%p, i32 %v) {
154 store i32 %v, i32* %p
155 ret void
156}
157
158; CHECK-LABEL: sti32_a8:
159; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000160; CHECK-NEXT: i32.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000161; CHECK-NEXT: return{{$}}
162define void @sti32_a8(i32 *%p, i32 %v) {
163 store i32 %v, i32* %p, align 8
164 ret void
165}
166
167; Truncating stores.
168
169; CHECK-LABEL: sti8_a1:
170; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000171; CHECK-NEXT: i32.store8 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000172; CHECK-NEXT: return{{$}}
173define void @sti8_a1(i8 *%p, i8 %v) {
174 store i8 %v, i8* %p, align 1
175 ret void
176}
177
178; CHECK-LABEL: sti8_a2:
179; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000180; CHECK-NEXT: i32.store8 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000181; CHECK-NEXT: return{{$}}
182define void @sti8_a2(i8 *%p, i8 %v) {
183 store i8 %v, i8* %p, align 2
184 ret void
185}
186
187; CHECK-LABEL: sti16_a1:
188; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000189; CHECK-NEXT: i32.store16 0($0):p2align=0, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000190; CHECK-NEXT: return{{$}}
191define void @sti16_a1(i16 *%p, i16 %v) {
192 store i16 %v, i16* %p, align 1
193 ret void
194}
195
196; CHECK-LABEL: sti16_a2:
197; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000198; CHECK-NEXT: i32.store16 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000199; CHECK-NEXT: return{{$}}
200define void @sti16_a2(i16 *%p, i16 %v) {
201 store i16 %v, i16* %p, align 2
202 ret void
203}
204
205; CHECK-LABEL: sti16_a4:
206; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000207; CHECK-NEXT: i32.store16 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000208; CHECK-NEXT: return{{$}}
209define void @sti16_a4(i16 *%p, i16 %v) {
210 store i16 %v, i16* %p, align 4
211 ret void
212}
Derek Schuff885dc592017-10-05 21:18:42 +0000213
214; Atomics.
215; Wasm atomics have the alignment field, but it must always have the
216; type's natural alignment.
217
218; CHECK-LABEL: ldi32_atomic_a4:
219; CHECK-NEXT: .param i32{{$}}
220; CHECK-NEXT: .result i32{{$}}
221; CHECK-NEXT: i32.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
222; CHECK-NEXT: return $pop[[NUM]]{{$}}
223define i32 @ldi32_atomic_a4(i32 *%p) {
224 %v = load atomic i32, i32* %p seq_cst, align 4
225 ret i32 %v
226}
227
228; 8 is greater than the default alignment so it is rounded down to 4
229
230; CHECK-LABEL: ldi32_atomic_a8:
231; CHECK-NEXT: .param i32{{$}}
232; CHECK-NEXT: .result i32{{$}}
233; CHECK-NEXT: i32.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
234; CHECK-NEXT: return $pop[[NUM]]{{$}}
235define i32 @ldi32_atomic_a8(i32 *%p) {
236 %v = load atomic i32, i32* %p seq_cst, align 8
237 ret i32 %v
238}