074bed17ce62985e78f69c60b2659035331bb23b
[oota-llvm.git] / test / CodeGen / WebAssembly / i32.ll
1 ; RUN: llc < %s -asm-verbose=false | FileCheck %s
2
3 ; Test that basic 32-bit integer operations assemble as expected.
4
5 target datalayout = "e-p:32:32-i64:64-n32:64-S128"
6 target triple = "wasm32-unknown-unknown"
7
8 declare i32 @llvm.ctlz.i32(i32, i1)
9 declare i32 @llvm.cttz.i32(i32, i1)
10 declare i32 @llvm.ctpop.i32(i32)
11
12 ; CHECK-LABEL: add32:
13 ; CHECK-NEXT: .param i32{{$}}
14 ; CHECK-NEXT: .param i32{{$}}
15 ; CHECK-NEXT: .result i32{{$}}
16 ; CHECK-NEXT: .local i32, i32, i32{{$}}
17 ; CHECK-NEXT: get_local push, 1{{$}}
18 ; CHECK-NEXT: set_local 2, pop{{$}}
19 ; CHECK-NEXT: get_local push, 0{{$}}
20 ; CHECK-NEXT: set_local 3, pop{{$}}
21 ; CHECK-NEXT: i32.add push, (get_local 3), (get_local 2){{$}}
22 ; CHECK-NEXT: set_local 4, pop{{$}}
23 ; CHECK-NEXT: return (get_local 4){{$}}
24 define i32 @add32(i32 %x, i32 %y) {
25   %a = add i32 %x, %y
26   ret i32 %a
27 }
28
29 ; CHECK-LABEL: sub32:
30 ; CHECK-NEXT: .param i32{{$}}
31 ; CHECK-NEXT: .param i32{{$}}
32 ; CHECK-NEXT: .result i32{{$}}
33 ; CHECK-NEXT: .local i32, i32, i32{{$}}
34 ; CHECK-NEXT: get_local push, 1{{$}}
35 ; CHECK-NEXT: set_local 2, pop{{$}}
36 ; CHECK-NEXT: get_local push, 0{{$}}
37 ; CHECK-NEXT: set_local 3, pop{{$}}
38 ; CHECK-NEXT: i32.sub push, (get_local 3), (get_local 2){{$}}
39 ; CHECK-NEXT: set_local 4, pop{{$}}
40 ; CHECK-NEXT: return (get_local 4){{$}}
41 define i32 @sub32(i32 %x, i32 %y) {
42   %a = sub i32 %x, %y
43   ret i32 %a
44 }
45
46 ; CHECK-LABEL: mul32:
47 ; CHECK-NEXT: .param i32{{$}}
48 ; CHECK-NEXT: .param i32{{$}}
49 ; CHECK-NEXT: .result i32{{$}}
50 ; CHECK-NEXT: .local i32, i32, i32{{$}}
51 ; CHECK-NEXT: get_local push, 1{{$}}
52 ; CHECK-NEXT: set_local 2, pop{{$}}
53 ; CHECK-NEXT: get_local push, 0{{$}}
54 ; CHECK-NEXT: set_local 3, pop{{$}}
55 ; CHECK-NEXT: i32.mul push, (get_local 3), (get_local 2){{$}}
56 ; CHECK-NEXT: set_local 4, pop{{$}}
57 ; CHECK-NEXT: return (get_local 4){{$}}
58 define i32 @mul32(i32 %x, i32 %y) {
59   %a = mul i32 %x, %y
60   ret i32 %a
61 }
62
63 ; CHECK-LABEL: sdiv32:
64 ; CHECK-NEXT: .param i32{{$}}
65 ; CHECK-NEXT: .param i32{{$}}
66 ; CHECK-NEXT: .result i32{{$}}
67 ; CHECK-NEXT: .local i32, i32, i32{{$}}
68 ; CHECK-NEXT: get_local push, 1{{$}}
69 ; CHECK-NEXT: set_local 2, pop{{$}}
70 ; CHECK-NEXT: get_local push, 0{{$}}
71 ; CHECK-NEXT: set_local 3, pop{{$}}
72 ; CHECK-NEXT: i32.div_s push, (get_local 3), (get_local 2){{$}}
73 ; CHECK-NEXT: set_local 4, pop{{$}}
74 ; CHECK-NEXT: return (get_local 4){{$}}
75 define i32 @sdiv32(i32 %x, i32 %y) {
76   %a = sdiv i32 %x, %y
77   ret i32 %a
78 }
79
80 ; CHECK-LABEL: udiv32:
81 ; CHECK-NEXT: .param i32{{$}}
82 ; CHECK-NEXT: .param i32{{$}}
83 ; CHECK-NEXT: .result i32{{$}}
84 ; CHECK-NEXT: .local i32, i32, i32{{$}}
85 ; CHECK-NEXT: get_local push, 1{{$}}
86 ; CHECK-NEXT: set_local 2, pop{{$}}
87 ; CHECK-NEXT: get_local push, 0{{$}}
88 ; CHECK-NEXT: set_local 3, pop{{$}}
89 ; CHECK-NEXT: i32.div_u push, (get_local 3), (get_local 2){{$}}
90 ; CHECK-NEXT: set_local 4, pop{{$}}
91 ; CHECK-NEXT: return (get_local 4){{$}}
92 define i32 @udiv32(i32 %x, i32 %y) {
93   %a = udiv i32 %x, %y
94   ret i32 %a
95 }
96
97 ; CHECK-LABEL: srem32:
98 ; CHECK-NEXT: .param i32{{$}}
99 ; CHECK-NEXT: .param i32{{$}}
100 ; CHECK-NEXT: .result i32{{$}}
101 ; CHECK-NEXT: .local i32, i32, i32{{$}}
102 ; CHECK-NEXT: get_local push, 1{{$}}
103 ; CHECK-NEXT: set_local 2, pop{{$}}
104 ; CHECK-NEXT: get_local push, 0{{$}}
105 ; CHECK-NEXT: set_local 3, pop{{$}}
106 ; CHECK-NEXT: i32.rem_s push, (get_local 3), (get_local 2){{$}}
107 ; CHECK-NEXT: set_local 4, pop{{$}}
108 ; CHECK-NEXT: return (get_local 4){{$}}
109 define i32 @srem32(i32 %x, i32 %y) {
110   %a = srem i32 %x, %y
111   ret i32 %a
112 }
113
114 ; CHECK-LABEL: urem32:
115 ; CHECK-NEXT: .param i32{{$}}
116 ; CHECK-NEXT: .param i32{{$}}
117 ; CHECK-NEXT: .result i32{{$}}
118 ; CHECK-NEXT: .local i32, i32, i32{{$}}
119 ; CHECK-NEXT: get_local push, 1{{$}}
120 ; CHECK-NEXT: set_local 2, pop{{$}}
121 ; CHECK-NEXT: get_local push, 0{{$}}
122 ; CHECK-NEXT: set_local 3, pop{{$}}
123 ; CHECK-NEXT: i32.rem_u push, (get_local 3), (get_local 2){{$}}
124 ; CHECK-NEXT: set_local 4, pop{{$}}
125 ; CHECK-NEXT: return (get_local 4){{$}}
126 define i32 @urem32(i32 %x, i32 %y) {
127   %a = urem i32 %x, %y
128   ret i32 %a
129 }
130
131 ; CHECK-LABEL: and32:
132 ; CHECK-NEXT: .param i32{{$}}
133 ; CHECK-NEXT: .param i32{{$}}
134 ; CHECK-NEXT: .result i32{{$}}
135 ; CHECK-NEXT: .local i32, i32, i32{{$}}
136 ; CHECK-NEXT: get_local push, 1{{$}}
137 ; CHECK-NEXT: set_local 2, pop{{$}}
138 ; CHECK-NEXT: get_local push, 0{{$}}
139 ; CHECK-NEXT: set_local 3, pop{{$}}
140 ; CHECK-NEXT: i32.and push, (get_local 3), (get_local 2){{$}}
141 ; CHECK-NEXT: set_local 4, pop{{$}}
142 ; CHECK-NEXT: return (get_local 4){{$}}
143 define i32 @and32(i32 %x, i32 %y) {
144   %a = and i32 %x, %y
145   ret i32 %a
146 }
147
148 ; CHECK-LABEL: or32:
149 ; CHECK-NEXT: .param i32{{$}}
150 ; CHECK-NEXT: .param i32{{$}}
151 ; CHECK-NEXT: .result i32{{$}}
152 ; CHECK-NEXT: .local i32, i32, i32{{$}}
153 ; CHECK-NEXT: get_local push, 1{{$}}
154 ; CHECK-NEXT: set_local 2, pop{{$}}
155 ; CHECK-NEXT: get_local push, 0{{$}}
156 ; CHECK-NEXT: set_local 3, pop{{$}}
157 ; CHECK-NEXT: i32.or push, (get_local 3), (get_local 2){{$}}
158 ; CHECK-NEXT: set_local 4, pop{{$}}
159 ; CHECK-NEXT: return (get_local 4){{$}}
160 define i32 @or32(i32 %x, i32 %y) {
161   %a = or i32 %x, %y
162   ret i32 %a
163 }
164
165 ; CHECK-LABEL: xor32:
166 ; CHECK-NEXT: .param i32{{$}}
167 ; CHECK-NEXT: .param i32{{$}}
168 ; CHECK-NEXT: .result i32{{$}}
169 ; CHECK-NEXT: .local i32, i32, i32{{$}}
170 ; CHECK-NEXT: get_local push, 1{{$}}
171 ; CHECK-NEXT: set_local 2, pop{{$}}
172 ; CHECK-NEXT: get_local push, 0{{$}}
173 ; CHECK-NEXT: set_local 3, pop{{$}}
174 ; CHECK-NEXT: i32.xor push, (get_local 3), (get_local 2){{$}}
175 ; CHECK-NEXT: set_local 4, pop{{$}}
176 ; CHECK-NEXT: return (get_local 4){{$}}
177 define i32 @xor32(i32 %x, i32 %y) {
178   %a = xor i32 %x, %y
179   ret i32 %a
180 }
181
182 ; CHECK-LABEL: shl32:
183 ; CHECK-NEXT: .param i32{{$}}
184 ; CHECK-NEXT: .param i32{{$}}
185 ; CHECK-NEXT: .result i32{{$}}
186 ; CHECK-NEXT: .local i32, i32, i32{{$}}
187 ; CHECK-NEXT: get_local push, 1{{$}}
188 ; CHECK-NEXT: set_local 2, pop{{$}}
189 ; CHECK-NEXT: get_local push, 0{{$}}
190 ; CHECK-NEXT: set_local 3, pop{{$}}
191 ; CHECK-NEXT: i32.shl push, (get_local 3), (get_local 2){{$}}
192 ; CHECK-NEXT: set_local 4, pop{{$}}
193 ; CHECK-NEXT: return (get_local 4){{$}}
194 define i32 @shl32(i32 %x, i32 %y) {
195   %a = shl i32 %x, %y
196   ret i32 %a
197 }
198
199 ; CHECK-LABEL: shr32:
200 ; CHECK-NEXT: .param i32{{$}}
201 ; CHECK-NEXT: .param i32{{$}}
202 ; CHECK-NEXT: .result i32{{$}}
203 ; CHECK-NEXT: .local i32, i32, i32{{$}}
204 ; CHECK-NEXT: get_local push, 1{{$}}
205 ; CHECK-NEXT: set_local 2, pop{{$}}
206 ; CHECK-NEXT: get_local push, 0{{$}}
207 ; CHECK-NEXT: set_local 3, pop{{$}}
208 ; CHECK-NEXT: i32.shr_u push, (get_local 3), (get_local 2){{$}}
209 ; CHECK-NEXT: set_local 4, pop{{$}}
210 ; CHECK-NEXT: return (get_local 4){{$}}
211 define i32 @shr32(i32 %x, i32 %y) {
212   %a = lshr i32 %x, %y
213   ret i32 %a
214 }
215
216 ; CHECK-LABEL: sar32:
217 ; CHECK-NEXT: .param i32{{$}}
218 ; CHECK-NEXT: .param i32{{$}}
219 ; CHECK-NEXT: .result i32{{$}}
220 ; CHECK-NEXT: .local i32, i32, i32{{$}}
221 ; CHECK-NEXT: get_local push, 1{{$}}
222 ; CHECK-NEXT: set_local 2, pop{{$}}
223 ; CHECK-NEXT: get_local push, 0{{$}}
224 ; CHECK-NEXT: set_local 3, pop{{$}}
225 ; CHECK-NEXT: i32.shr_s push, (get_local 3), (get_local 2){{$}}
226 ; CHECK-NEXT: set_local 4, pop{{$}}
227 ; CHECK-NEXT: return (get_local 4){{$}}
228 define i32 @sar32(i32 %x, i32 %y) {
229   %a = ashr i32 %x, %y
230   ret i32 %a
231 }
232
233 ; CHECK-LABEL: clz32:
234 ; CHECK-NEXT: .param i32{{$}}
235 ; CHECK-NEXT: .result i32{{$}}
236 ; CHECK-NEXT: .local i32, i32{{$}}
237 ; CHECK-NEXT: get_local push, 0{{$}}
238 ; CHECK-NEXT: set_local 1, pop{{$}}
239 ; CHECK-NEXT: i32.clz push, (get_local 1){{$}}
240 ; CHECK-NEXT: set_local 2, pop{{$}}
241 ; CHECK-NEXT: return (get_local 2){{$}}
242 define i32 @clz32(i32 %x) {
243   %a = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
244   ret i32 %a
245 }
246
247 ; CHECK-LABEL: clz32_zero_undef:
248 ; CHECK-NEXT: .param i32{{$}}
249 ; CHECK-NEXT: .result i32{{$}}
250 ; CHECK-NEXT: .local i32, i32{{$}}
251 ; CHECK-NEXT: get_local push, 0{{$}}
252 ; CHECK-NEXT: set_local 1, pop{{$}}
253 ; CHECK-NEXT: i32.clz push, (get_local 1){{$}}
254 ; CHECK-NEXT: set_local 2, pop{{$}}
255 ; CHECK-NEXT: return (get_local 2){{$}}
256 define i32 @clz32_zero_undef(i32 %x) {
257   %a = call i32 @llvm.ctlz.i32(i32 %x, i1 true)
258   ret i32 %a
259 }
260
261 ; CHECK-LABEL: ctz32:
262 ; CHECK-NEXT: .param i32{{$}}
263 ; CHECK-NEXT: .result i32{{$}}
264 ; CHECK-NEXT: .local i32, i32{{$}}
265 ; CHECK-NEXT: get_local push, 0{{$}}
266 ; CHECK-NEXT: set_local 1, pop{{$}}
267 ; CHECK-NEXT: i32.ctz push, (get_local 1){{$}}
268 ; CHECK-NEXT: set_local 2, pop{{$}}
269 ; CHECK-NEXT: return (get_local 2){{$}}
270 define i32 @ctz32(i32 %x) {
271   %a = call i32 @llvm.cttz.i32(i32 %x, i1 false)
272   ret i32 %a
273 }
274
275 ; CHECK-LABEL: ctz32_zero_undef:
276 ; CHECK-NEXT: .param i32{{$}}
277 ; CHECK-NEXT: .result i32{{$}}
278 ; CHECK-NEXT: .local i32, i32{{$}}
279 ; CHECK-NEXT: get_local push, 0{{$}}
280 ; CHECK-NEXT: set_local 1, pop{{$}}
281 ; CHECK-NEXT: i32.ctz push, (get_local 1){{$}}
282 ; CHECK-NEXT: set_local 2, pop{{$}}
283 ; CHECK-NEXT: return (get_local 2){{$}}
284 define i32 @ctz32_zero_undef(i32 %x) {
285   %a = call i32 @llvm.cttz.i32(i32 %x, i1 true)
286   ret i32 %a
287 }
288
289 ; CHECK-LABEL: popcnt32:
290 ; CHECK-NEXT: .param i32{{$}}
291 ; CHECK-NEXT: .result i32{{$}}
292 ; CHECK-NEXT: .local i32, i32{{$}}
293 ; CHECK-NEXT: get_local push, 0{{$}}
294 ; CHECK-NEXT: set_local 1, pop{{$}}
295 ; CHECK-NEXT: i32.popcnt push, (get_local 1){{$}}
296 ; CHECK-NEXT: set_local 2, pop{{$}}
297 ; CHECK-NEXT: return (get_local 2){{$}}
298 define i32 @popcnt32(i32 %x) {
299   %a = call i32 @llvm.ctpop.i32(i32 %x)
300   ret i32 %a
301 }