blob: a4ce351dc267bc0eff4ead1382667df4769efe79 [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: ldi32_a1:
11; CHECK-NEXT: .param i32{{$}}
12; CHECK-NEXT: .result i32{{$}}
13; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
14; CHECK-NEXT: return $pop[[NUM]]{{$}}
15define i32 @ldi32_a1(i32 *%p) {
16 %v = load i32, i32* %p, align 1
17 ret i32 %v
18}
19
20; CHECK-LABEL: ldi32_a2:
21; CHECK-NEXT: .param i32{{$}}
22; CHECK-NEXT: .result i32{{$}}
23; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
24; CHECK-NEXT: return $pop[[NUM]]{{$}}
25define i32 @ldi32_a2(i32 *%p) {
26 %v = load i32, i32* %p, align 2
27 ret i32 %v
28}
29
30; 4 is the default alignment for i32 so no attribute is needed.
31
32; CHECK-LABEL: ldi32_a4:
33; CHECK-NEXT: .param i32{{$}}
34; CHECK-NEXT: .result i32{{$}}
35; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
36; CHECK-NEXT: return $pop[[NUM]]{{$}}
37define i32 @ldi32_a4(i32 *%p) {
38 %v = load i32, i32* %p, align 4
39 ret i32 %v
40}
41
42; The default alignment in LLVM is the same as the defualt alignment in wasm.
43
44; CHECK-LABEL: ldi32:
45; CHECK-NEXT: .param i32{{$}}
46; CHECK-NEXT: .result i32{{$}}
47; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
48; CHECK-NEXT: return $pop[[NUM]]{{$}}
49define i32 @ldi32(i32 *%p) {
50 %v = load i32, i32* %p
51 ret i32 %v
52}
53
Dan Gohman04e7fb72016-04-21 23:59:48 +000054; 8 is greater than the default alignment so it is ignored.
55
Dan Gohmanbb372242016-01-26 03:39:31 +000056; CHECK-LABEL: ldi32_a8:
57; CHECK-NEXT: .param i32{{$}}
58; CHECK-NEXT: .result i32{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +000059; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +000060; CHECK-NEXT: return $pop[[NUM]]{{$}}
61define i32 @ldi32_a8(i32 *%p) {
62 %v = load i32, i32* %p, align 8
63 ret i32 %v
64}
65
66; Extending loads.
67
68; CHECK-LABEL: ldi8_a1:
69; CHECK-NEXT: .param i32{{$}}
70; CHECK-NEXT: .result i32{{$}}
71; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
72; CHECK-NEXT: return $pop[[NUM]]{{$}}
73define i8 @ldi8_a1(i8 *%p) {
74 %v = load i8, i8* %p, align 1
75 ret i8 %v
76}
77
78; CHECK-LABEL: ldi8_a2:
79; CHECK-NEXT: .param i32{{$}}
80; CHECK-NEXT: .result i32{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +000081; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +000082; CHECK-NEXT: return $pop[[NUM]]{{$}}
83define i8 @ldi8_a2(i8 *%p) {
84 %v = load i8, i8* %p, align 2
85 ret i8 %v
86}
87
88; CHECK-LABEL: ldi16_a1:
89; CHECK-NEXT: .param i32{{$}}
90; CHECK-NEXT: .result i32{{$}}
91; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
92; CHECK-NEXT: return $pop[[NUM]]{{$}}
93define i16 @ldi16_a1(i16 *%p) {
94 %v = load i16, i16* %p, align 1
95 ret i16 %v
96}
97
98; CHECK-LABEL: ldi16_a2:
99; CHECK-NEXT: .param i32{{$}}
100; CHECK-NEXT: .result i32{{$}}
101; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
102; CHECK-NEXT: return $pop[[NUM]]{{$}}
103define i16 @ldi16_a2(i16 *%p) {
104 %v = load i16, i16* %p, align 2
105 ret i16 %v
106}
107
108; CHECK-LABEL: ldi16_a4:
109; CHECK-NEXT: .param i32{{$}}
110; CHECK-NEXT: .result i32{{$}}
Dan Gohman04e7fb72016-04-21 23:59:48 +0000111; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000112; CHECK-NEXT: return $pop[[NUM]]{{$}}
113define i16 @ldi16_a4(i16 *%p) {
114 %v = load i16, i16* %p, align 4
115 ret i16 %v
116}
117
118; Stores.
119
120; CHECK-LABEL: sti32_a1:
121; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000122; CHECK-NEXT: i32.store 0($0):p2align=0, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000123; CHECK-NEXT: return{{$}}
124define void @sti32_a1(i32 *%p, i32 %v) {
125 store i32 %v, i32* %p, align 1
126 ret void
127}
128
129; CHECK-LABEL: sti32_a2:
130; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000131; CHECK-NEXT: i32.store 0($0):p2align=1, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000132; CHECK-NEXT: return{{$}}
133define void @sti32_a2(i32 *%p, i32 %v) {
134 store i32 %v, i32* %p, align 2
135 ret void
136}
137
138; 4 is the default alignment for i32 so no attribute is needed.
139
140; CHECK-LABEL: sti32_a4:
141; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000142; CHECK-NEXT: i32.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000143; CHECK-NEXT: return{{$}}
144define void @sti32_a4(i32 *%p, i32 %v) {
145 store i32 %v, i32* %p, align 4
146 ret void
147}
148
149; The default alignment in LLVM is the same as the defualt alignment in wasm.
150
151; CHECK-LABEL: sti32:
152; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000153; CHECK-NEXT: i32.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000154; CHECK-NEXT: return{{$}}
155define void @sti32(i32 *%p, i32 %v) {
156 store i32 %v, i32* %p
157 ret void
158}
159
160; CHECK-LABEL: sti32_a8:
161; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000162; CHECK-NEXT: i32.store 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000163; CHECK-NEXT: return{{$}}
164define void @sti32_a8(i32 *%p, i32 %v) {
165 store i32 %v, i32* %p, align 8
166 ret void
167}
168
169; Truncating stores.
170
171; CHECK-LABEL: sti8_a1:
172; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000173; CHECK-NEXT: i32.store8 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000174; CHECK-NEXT: return{{$}}
175define void @sti8_a1(i8 *%p, i8 %v) {
176 store i8 %v, i8* %p, align 1
177 ret void
178}
179
180; CHECK-LABEL: sti8_a2:
181; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000182; CHECK-NEXT: i32.store8 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000183; CHECK-NEXT: return{{$}}
184define void @sti8_a2(i8 *%p, i8 %v) {
185 store i8 %v, i8* %p, align 2
186 ret void
187}
188
189; CHECK-LABEL: sti16_a1:
190; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000191; CHECK-NEXT: i32.store16 0($0):p2align=0, $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000192; CHECK-NEXT: return{{$}}
193define void @sti16_a1(i16 *%p, i16 %v) {
194 store i16 %v, i16* %p, align 1
195 ret void
196}
197
198; CHECK-LABEL: sti16_a2:
199; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000200; CHECK-NEXT: i32.store16 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000201; CHECK-NEXT: return{{$}}
202define void @sti16_a2(i16 *%p, i16 %v) {
203 store i16 %v, i16* %p, align 2
204 ret void
205}
206
207; CHECK-LABEL: sti16_a4:
208; CHECK-NEXT: .param i32, i32{{$}}
Dan Gohman7f1bdb22016-10-06 22:08:28 +0000209; CHECK-NEXT: i32.store16 0($0), $1{{$}}
Dan Gohmanbb372242016-01-26 03:39:31 +0000210; CHECK-NEXT: return{{$}}
211define void @sti16_a4(i16 *%p, i16 %v) {
212 store i16 %v, i16* %p, align 4
213 ret void
214}
Derek Schuff885dc592017-10-05 21:18:42 +0000215
216; Atomics.
217; Wasm atomics have the alignment field, but it must always have the
218; type's natural alignment.
219
220; CHECK-LABEL: ldi32_atomic_a4:
221; CHECK-NEXT: .param i32{{$}}
222; CHECK-NEXT: .result i32{{$}}
223; CHECK-NEXT: i32.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
224; CHECK-NEXT: return $pop[[NUM]]{{$}}
225define i32 @ldi32_atomic_a4(i32 *%p) {
226 %v = load atomic i32, i32* %p seq_cst, align 4
227 ret i32 %v
228}
229
230; 8 is greater than the default alignment so it is rounded down to 4
231
232; CHECK-LABEL: ldi32_atomic_a8:
233; CHECK-NEXT: .param i32{{$}}
234; CHECK-NEXT: .result i32{{$}}
235; CHECK-NEXT: i32.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
236; CHECK-NEXT: return $pop[[NUM]]{{$}}
237define i32 @ldi32_atomic_a8(i32 *%p) {
238 %v = load atomic i32, i32* %p seq_cst, align 8
239 ret i32 %v
240}
Heejin Ahn402b4902018-07-02 21:22:59 +0000241
242; CHECK-LABEL: sti32_atomic_a4:
243; CHECK-NEXT: .param i32, i32{{$}}
244; CHECK-NEXT: i32.atomic.store 0($0), $1{{$}}
245; CHECK-NEXT: return{{$}}
246define void @sti32_atomic_a4(i32 *%p, i32 %v) {
247 store atomic i32 %v, i32* %p seq_cst, align 4
248 ret void
249}
250
251; CHECK-LABEL: sti32_atomic_a8:
252; CHECK-NEXT: .param i32, i32{{$}}
253; CHECK-NEXT: i32.atomic.store 0($0), $1{{$}}
254; CHECK-NEXT: return{{$}}
255define void @sti32_atomic_a8(i32 *%p, i32 %v) {
256 store atomic i32 %v, i32* %p seq_cst, align 8
257 ret void
258}