[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / WebAssembly / i32-load-store-alignment.ll
blob082b1083ee55f9b8ad2e3cdd1676fe1d8ed416a0
1 ; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s
3 ; Test loads and stores with custom alignment values.
5 target triple = "wasm32-unknown-unknown"
7 ;===----------------------------------------------------------------------------
8 ; Loads
9 ;===----------------------------------------------------------------------------
11 ; CHECK-LABEL: ldi32_a1:
12 ; CHECK-NEXT: .functype ldi32_a1 (i32) -> (i32){{$}}
13 ; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
14 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
15 define i32 @ldi32_a1(i32 *%p) {
16   %v = load i32, i32* %p, align 1
17   ret i32 %v
20 ; CHECK-LABEL: ldi32_a2:
21 ; CHECK-NEXT: .functype ldi32_a2 (i32) -> (i32){{$}}
22 ; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
23 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
24 define i32 @ldi32_a2(i32 *%p) {
25   %v = load i32, i32* %p, align 2
26   ret i32 %v
29 ; 4 is the default alignment for i32 so no attribute is needed.
31 ; CHECK-LABEL: ldi32_a4:
32 ; CHECK-NEXT: .functype ldi32_a4 (i32) -> (i32){{$}}
33 ; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
34 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
35 define i32 @ldi32_a4(i32 *%p) {
36   %v = load i32, i32* %p, align 4
37   ret i32 %v
40 ; The default alignment in LLVM is the same as the default alignment in wasm.
42 ; CHECK-LABEL: ldi32:
43 ; CHECK-NEXT: .functype ldi32 (i32) -> (i32){{$}}
44 ; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
45 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
46 define i32 @ldi32(i32 *%p) {
47   %v = load i32, i32* %p
48   ret i32 %v
51 ; 8 is greater than the default alignment so it is ignored.
53 ; CHECK-LABEL: ldi32_a8:
54 ; CHECK-NEXT: .functype ldi32_a8 (i32) -> (i32){{$}}
55 ; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
56 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
57 define i32 @ldi32_a8(i32 *%p) {
58   %v = load i32, i32* %p, align 8
59   ret i32 %v
62 ;===----------------------------------------------------------------------------
63 ; Extending loads
64 ;===----------------------------------------------------------------------------
66 ; CHECK-LABEL: ldi8_a1:
67 ; CHECK-NEXT: .functype ldi8_a1 (i32) -> (i32){{$}}
68 ; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
69 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
70 define i8 @ldi8_a1(i8 *%p) {
71   %v = load i8, i8* %p, align 1
72   ret i8 %v
75 ; CHECK-LABEL: ldi8_a2:
76 ; CHECK-NEXT: .functype ldi8_a2 (i32) -> (i32){{$}}
77 ; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
78 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
79 define i8 @ldi8_a2(i8 *%p) {
80   %v = load i8, i8* %p, align 2
81   ret i8 %v
84 ; CHECK-LABEL: ldi16_a1:
85 ; CHECK-NEXT: .functype ldi16_a1 (i32) -> (i32){{$}}
86 ; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
87 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
88 define i16 @ldi16_a1(i16 *%p) {
89   %v = load i16, i16* %p, align 1
90   ret i16 %v
93 ; CHECK-LABEL: ldi16_a2:
94 ; CHECK-NEXT: .functype ldi16_a2 (i32) -> (i32){{$}}
95 ; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
96 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
97 define i16 @ldi16_a2(i16 *%p) {
98   %v = load i16, i16* %p, align 2
99   ret i16 %v
102 ; CHECK-LABEL: ldi16_a4:
103 ; CHECK-NEXT: .functype ldi16_a4 (i32) -> (i32){{$}}
104 ; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
105 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
106 define i16 @ldi16_a4(i16 *%p) {
107   %v = load i16, i16* %p, align 4
108   ret i16 %v
111 ;===----------------------------------------------------------------------------
112 ; Stores
113 ;===----------------------------------------------------------------------------
115 ; CHECK-LABEL: sti32_a1:
116 ; CHECK-NEXT: .functype sti32_a1 (i32, i32) -> (){{$}}
117 ; CHECK-NEXT: i32.store 0($0):p2align=0, $1{{$}}
118 ; CHECK-NEXT: return{{$}}
119 define void @sti32_a1(i32 *%p, i32 %v) {
120   store i32 %v, i32* %p, align 1
121   ret void
124 ; CHECK-LABEL: sti32_a2:
125 ; CHECK-NEXT: .functype sti32_a2 (i32, i32) -> (){{$}}
126 ; CHECK-NEXT: i32.store 0($0):p2align=1, $1{{$}}
127 ; CHECK-NEXT: return{{$}}
128 define void @sti32_a2(i32 *%p, i32 %v) {
129   store i32 %v, i32* %p, align 2
130   ret void
133 ; 4 is the default alignment for i32 so no attribute is needed.
135 ; CHECK-LABEL: sti32_a4:
136 ; CHECK-NEXT: .functype sti32_a4 (i32, i32) -> (){{$}}
137 ; CHECK-NEXT: i32.store 0($0), $1{{$}}
138 ; CHECK-NEXT: return{{$}}
139 define void @sti32_a4(i32 *%p, i32 %v) {
140   store i32 %v, i32* %p, align 4
141   ret void
144 ; The default alignment in LLVM is the same as the default alignment in wasm.
146 ; CHECK-LABEL: sti32:
147 ; CHECK-NEXT: .functype sti32 (i32, i32) -> (){{$}}
148 ; CHECK-NEXT: i32.store 0($0), $1{{$}}
149 ; CHECK-NEXT: return{{$}}
150 define void @sti32(i32 *%p, i32 %v) {
151   store i32 %v, i32* %p
152   ret void
155 ; CHECK-LABEL: sti32_a8:
156 ; CHECK-NEXT: .functype sti32_a8 (i32, i32) -> (){{$}}
157 ; CHECK-NEXT: i32.store 0($0), $1{{$}}
158 ; CHECK-NEXT: return{{$}}
159 define void @sti32_a8(i32 *%p, i32 %v) {
160   store i32 %v, i32* %p, align 8
161   ret void
164 ;===----------------------------------------------------------------------------
165 ; Truncating stores
166 ;===----------------------------------------------------------------------------
168 ; CHECK-LABEL: sti8_a1:
169 ; CHECK-NEXT: .functype sti8_a1 (i32, i32) -> (){{$}}
170 ; CHECK-NEXT: i32.store8 0($0), $1{{$}}
171 ; CHECK-NEXT: return{{$}}
172 define void @sti8_a1(i8 *%p, i8 %v) {
173   store i8 %v, i8* %p, align 1
174   ret void
177 ; CHECK-LABEL: sti8_a2:
178 ; CHECK-NEXT: .functype sti8_a2 (i32, i32) -> (){{$}}
179 ; CHECK-NEXT: i32.store8 0($0), $1{{$}}
180 ; CHECK-NEXT: return{{$}}
181 define void @sti8_a2(i8 *%p, i8 %v) {
182   store i8 %v, i8* %p, align 2
183   ret void
186 ; CHECK-LABEL: sti16_a1:
187 ; CHECK-NEXT: .functype sti16_a1 (i32, i32) -> (){{$}}
188 ; CHECK-NEXT: i32.store16 0($0):p2align=0, $1{{$}}
189 ; CHECK-NEXT: return{{$}}
190 define void @sti16_a1(i16 *%p, i16 %v) {
191   store i16 %v, i16* %p, align 1
192   ret void
195 ; CHECK-LABEL: sti16_a2:
196 ; CHECK-NEXT: .functype sti16_a2 (i32, i32) -> (){{$}}
197 ; CHECK-NEXT: i32.store16 0($0), $1{{$}}
198 ; CHECK-NEXT: return{{$}}
199 define void @sti16_a2(i16 *%p, i16 %v) {
200   store i16 %v, i16* %p, align 2
201   ret void
204 ; CHECK-LABEL: sti16_a4:
205 ; CHECK-NEXT: .functype sti16_a4 (i32, i32) -> (){{$}}
206 ; CHECK-NEXT: i32.store16 0($0), $1{{$}}
207 ; CHECK-NEXT: return{{$}}
208 define void @sti16_a4(i16 *%p, i16 %v) {
209   store i16 %v, i16* %p, align 4
210   ret void
213 ;===----------------------------------------------------------------------------
214 ; Atomic loads
215 ;===----------------------------------------------------------------------------
217 ; Wasm atomics have the alignment field, but it must always have the type's
218 ; natural alignment.
220 ; CHECK-LABEL: ldi32_atomic_a4:
221 ; CHECK-NEXT: .functype ldi32_atomic_a4 (i32) -> (i32){{$}}
222 ; CHECK-NEXT: i32.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
223 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
224 define i32 @ldi32_atomic_a4(i32 *%p) {
225   %v = load atomic i32, i32* %p seq_cst, align 4
226   ret i32 %v
229 ; 8 is greater than the default alignment so it is ignored.
231 ; CHECK-LABEL: ldi32_atomic_a8:
232 ; CHECK-NEXT: .functype ldi32_atomic_a8 (i32) -> (i32){{$}}
233 ; CHECK-NEXT: i32.atomic.load $push[[NUM:[0-9]+]]=, 0($0){{$}}
234 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
235 define i32 @ldi32_atomic_a8(i32 *%p) {
236   %v = load atomic i32, i32* %p seq_cst, align 8
237   ret i32 %v
240 ;===----------------------------------------------------------------------------
241 ; Atomic stores
242 ;===----------------------------------------------------------------------------
244 ; CHECK-LABEL: sti32_atomic_a4:
245 ; CHECK-NEXT: .functype sti32_atomic_a4 (i32, i32) -> (){{$}}
246 ; CHECK-NEXT: i32.atomic.store 0($0), $1{{$}}
247 ; CHECK-NEXT: return{{$}}
248 define void @sti32_atomic_a4(i32 *%p, i32 %v) {
249  store atomic i32 %v, i32* %p seq_cst, align 4
250  ret void
253 ; 8 is greater than the default alignment so it is ignored.
255 ; CHECK-LABEL: sti32_atomic_a8:
256 ; CHECK-NEXT: .functype sti32_atomic_a8 (i32, i32) -> (){{$}}
257 ; CHECK-NEXT: i32.atomic.store 0($0), $1{{$}}
258 ; CHECK-NEXT: return{{$}}
259 define void @sti32_atomic_a8(i32 *%p, i32 %v) {
260  store atomic i32 %v, i32* %p seq_cst, align 8
261  ret void