blob: 89279fba1e5fc1c515fbcaa03fa61c3c2cc6bcbb [file] [log] [blame]
Dan Gohmanbb372242016-01-26 03:39:31 +00001; RUN: llc < %s -asm-verbose=false | FileCheck %s
2
3; Test loads and stores with custom alignment values.
4
5target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
6target triple = "wasm32-unknown-unknown"
7
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
52; CHECK-LABEL: ldi32_a8:
53; CHECK-NEXT: .param i32{{$}}
54; CHECK-NEXT: .result i32{{$}}
55; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=3{{$}}
56; CHECK-NEXT: return $pop[[NUM]]{{$}}
57define i32 @ldi32_a8(i32 *%p) {
58 %v = load i32, i32* %p, align 8
59 ret i32 %v
60}
61
62; Extending loads.
63
64; CHECK-LABEL: ldi8_a1:
65; CHECK-NEXT: .param i32{{$}}
66; CHECK-NEXT: .result i32{{$}}
67; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
68; CHECK-NEXT: return $pop[[NUM]]{{$}}
69define i8 @ldi8_a1(i8 *%p) {
70 %v = load i8, i8* %p, align 1
71 ret i8 %v
72}
73
74; CHECK-LABEL: ldi8_a2:
75; CHECK-NEXT: .param i32{{$}}
76; CHECK-NEXT: .result i32{{$}}
77; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}}
78; CHECK-NEXT: return $pop[[NUM]]{{$}}
79define i8 @ldi8_a2(i8 *%p) {
80 %v = load i8, i8* %p, align 2
81 ret i8 %v
82}
83
84; CHECK-LABEL: ldi16_a1:
85; CHECK-NEXT: .param i32{{$}}
86; CHECK-NEXT: .result i32{{$}}
87; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=0{{$}}
88; CHECK-NEXT: return $pop[[NUM]]{{$}}
89define i16 @ldi16_a1(i16 *%p) {
90 %v = load i16, i16* %p, align 1
91 ret i16 %v
92}
93
94; CHECK-LABEL: ldi16_a2:
95; CHECK-NEXT: .param i32{{$}}
96; CHECK-NEXT: .result i32{{$}}
97; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}}
98; CHECK-NEXT: return $pop[[NUM]]{{$}}
99define i16 @ldi16_a2(i16 *%p) {
100 %v = load i16, i16* %p, align 2
101 ret i16 %v
102}
103
104; CHECK-LABEL: ldi16_a4:
105; CHECK-NEXT: .param i32{{$}}
106; CHECK-NEXT: .result i32{{$}}
107; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=2{{$}}
108; CHECK-NEXT: return $pop[[NUM]]{{$}}
109define i16 @ldi16_a4(i16 *%p) {
110 %v = load i16, i16* %p, align 4
111 ret i16 %v
112}
113
114; Stores.
115
116; CHECK-LABEL: sti32_a1:
117; CHECK-NEXT: .param i32, i32{{$}}
118; CHECK-NEXT: i32.store $discard=, 0($0):p2align=0, $1{{$}}
119; CHECK-NEXT: return{{$}}
120define void @sti32_a1(i32 *%p, i32 %v) {
121 store i32 %v, i32* %p, align 1
122 ret void
123}
124
125; CHECK-LABEL: sti32_a2:
126; CHECK-NEXT: .param i32, i32{{$}}
127; CHECK-NEXT: i32.store $discard=, 0($0):p2align=1, $1{{$}}
128; CHECK-NEXT: return{{$}}
129define void @sti32_a2(i32 *%p, i32 %v) {
130 store i32 %v, i32* %p, align 2
131 ret void
132}
133
134; 4 is the default alignment for i32 so no attribute is needed.
135
136; CHECK-LABEL: sti32_a4:
137; CHECK-NEXT: .param i32, i32{{$}}
138; CHECK-NEXT: i32.store $discard=, 0($0), $1{{$}}
139; CHECK-NEXT: return{{$}}
140define void @sti32_a4(i32 *%p, i32 %v) {
141 store i32 %v, i32* %p, align 4
142 ret void
143}
144
145; The default alignment in LLVM is the same as the defualt alignment in wasm.
146
147; CHECK-LABEL: sti32:
148; CHECK-NEXT: .param i32, i32{{$}}
149; CHECK-NEXT: i32.store $discard=, 0($0), $1{{$}}
150; CHECK-NEXT: return{{$}}
151define void @sti32(i32 *%p, i32 %v) {
152 store i32 %v, i32* %p
153 ret void
154}
155
156; CHECK-LABEL: sti32_a8:
157; CHECK-NEXT: .param i32, i32{{$}}
158; CHECK-NEXT: i32.store $discard=, 0($0):p2align=3, $1{{$}}
159; CHECK-NEXT: return{{$}}
160define void @sti32_a8(i32 *%p, i32 %v) {
161 store i32 %v, i32* %p, align 8
162 ret void
163}
164
165; Truncating stores.
166
167; CHECK-LABEL: sti8_a1:
168; CHECK-NEXT: .param i32, i32{{$}}
169; CHECK-NEXT: i32.store8 $discard=, 0($0), $1{{$}}
170; CHECK-NEXT: return{{$}}
171define void @sti8_a1(i8 *%p, i8 %v) {
172 store i8 %v, i8* %p, align 1
173 ret void
174}
175
176; CHECK-LABEL: sti8_a2:
177; CHECK-NEXT: .param i32, i32{{$}}
178; CHECK-NEXT: i32.store8 $discard=, 0($0):p2align=1, $1{{$}}
179; CHECK-NEXT: return{{$}}
180define void @sti8_a2(i8 *%p, i8 %v) {
181 store i8 %v, i8* %p, align 2
182 ret void
183}
184
185; CHECK-LABEL: sti16_a1:
186; CHECK-NEXT: .param i32, i32{{$}}
187; CHECK-NEXT: i32.store16 $discard=, 0($0):p2align=0, $1{{$}}
188; CHECK-NEXT: return{{$}}
189define void @sti16_a1(i16 *%p, i16 %v) {
190 store i16 %v, i16* %p, align 1
191 ret void
192}
193
194; CHECK-LABEL: sti16_a2:
195; CHECK-NEXT: .param i32, i32{{$}}
196; CHECK-NEXT: i32.store16 $discard=, 0($0), $1{{$}}
197; CHECK-NEXT: return{{$}}
198define void @sti16_a2(i16 *%p, i16 %v) {
199 store i16 %v, i16* %p, align 2
200 ret void
201}
202
203; CHECK-LABEL: sti16_a4:
204; CHECK-NEXT: .param i32, i32{{$}}
205; CHECK-NEXT: i32.store16 $discard=, 0($0):p2align=2, $1{{$}}
206; CHECK-NEXT: return{{$}}
207define void @sti16_a4(i16 *%p, i16 %v) {
208 store i16 %v, i16* %p, align 4
209 ret void
210}