51d9549b4d30eddd9bbca803b262d86fdf3d5a97
[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: i32.add $push, (get_local 0), (get_local 1){{$}}
18 ; CHECK-NEXT: set_local 2, $pop{{$}}
19 ; CHECK-NEXT: return (get_local 2){{$}}
20 define i32 @add32(i32 %x, i32 %y) {
21   %a = add i32 %x, %y
22   ret i32 %a
23 }
24
25 ; CHECK-LABEL: sub32:
26 ; CHECK-NEXT: .param i32{{$}}
27 ; CHECK-NEXT: .param i32{{$}}
28 ; CHECK-NEXT: .result i32{{$}}
29 ; CHECK-NEXT: .local i32, i32, i32{{$}}
30 ; CHECK-NEXT: i32.sub $push, (get_local 0), (get_local 1){{$}}
31 ; CHECK-NEXT: set_local 2, $pop{{$}}
32 ; CHECK-NEXT: return (get_local 2){{$}}
33 define i32 @sub32(i32 %x, i32 %y) {
34   %a = sub i32 %x, %y
35   ret i32 %a
36 }
37
38 ; CHECK-LABEL: mul32:
39 ; CHECK-NEXT: .param i32{{$}}
40 ; CHECK-NEXT: .param i32{{$}}
41 ; CHECK-NEXT: .result i32{{$}}
42 ; CHECK-NEXT: .local i32, i32, i32{{$}}
43 ; CHECK-NEXT: i32.mul $push, (get_local 0), (get_local 1){{$}}
44 ; CHECK-NEXT: set_local 2, $pop{{$}}
45 ; CHECK-NEXT: return (get_local 2){{$}}
46 define i32 @mul32(i32 %x, i32 %y) {
47   %a = mul i32 %x, %y
48   ret i32 %a
49 }
50
51 ; CHECK-LABEL: sdiv32:
52 ; CHECK-NEXT: .param i32{{$}}
53 ; CHECK-NEXT: .param i32{{$}}
54 ; CHECK-NEXT: .result i32{{$}}
55 ; CHECK-NEXT: .local i32, i32, i32{{$}}
56 ; CHECK-NEXT: i32.div_s $push, (get_local 0), (get_local 1){{$}}
57 ; CHECK-NEXT: set_local 2, $pop{{$}}
58 ; CHECK-NEXT: return (get_local 2){{$}}
59 define i32 @sdiv32(i32 %x, i32 %y) {
60   %a = sdiv i32 %x, %y
61   ret i32 %a
62 }
63
64 ; CHECK-LABEL: udiv32:
65 ; CHECK-NEXT: .param i32{{$}}
66 ; CHECK-NEXT: .param i32{{$}}
67 ; CHECK-NEXT: .result i32{{$}}
68 ; CHECK-NEXT: .local i32, i32, i32{{$}}
69 ; CHECK-NEXT: i32.div_u $push, (get_local 0), (get_local 1){{$}}
70 ; CHECK-NEXT: set_local 2, $pop{{$}}
71 ; CHECK-NEXT: return (get_local 2){{$}}
72 define i32 @udiv32(i32 %x, i32 %y) {
73   %a = udiv i32 %x, %y
74   ret i32 %a
75 }
76
77 ; CHECK-LABEL: srem32:
78 ; CHECK-NEXT: .param i32{{$}}
79 ; CHECK-NEXT: .param i32{{$}}
80 ; CHECK-NEXT: .result i32{{$}}
81 ; CHECK-NEXT: .local i32, i32, i32{{$}}
82 ; CHECK-NEXT: i32.rem_s $push, (get_local 0), (get_local 1){{$}}
83 ; CHECK-NEXT: set_local 2, $pop{{$}}
84 ; CHECK-NEXT: return (get_local 2){{$}}
85 define i32 @srem32(i32 %x, i32 %y) {
86   %a = srem i32 %x, %y
87   ret i32 %a
88 }
89
90 ; CHECK-LABEL: urem32:
91 ; CHECK-NEXT: .param i32{{$}}
92 ; CHECK-NEXT: .param i32{{$}}
93 ; CHECK-NEXT: .result i32{{$}}
94 ; CHECK-NEXT: .local i32, i32, i32{{$}}
95 ; CHECK-NEXT: i32.rem_u $push, (get_local 0), (get_local 1){{$}}
96 ; CHECK-NEXT: set_local 2, $pop{{$}}
97 ; CHECK-NEXT: return (get_local 2){{$}}
98 define i32 @urem32(i32 %x, i32 %y) {
99   %a = urem i32 %x, %y
100   ret i32 %a
101 }
102
103 ; CHECK-LABEL: and32:
104 ; CHECK-NEXT: .param i32{{$}}
105 ; CHECK-NEXT: .param i32{{$}}
106 ; CHECK-NEXT: .result i32{{$}}
107 ; CHECK-NEXT: .local i32, i32, i32{{$}}
108 ; CHECK-NEXT: i32.and $push, (get_local 0), (get_local 1){{$}}
109 ; CHECK-NEXT: set_local 2, $pop{{$}}
110 ; CHECK-NEXT: return (get_local 2){{$}}
111 define i32 @and32(i32 %x, i32 %y) {
112   %a = and i32 %x, %y
113   ret i32 %a
114 }
115
116 ; CHECK-LABEL: or32:
117 ; CHECK-NEXT: .param i32{{$}}
118 ; CHECK-NEXT: .param i32{{$}}
119 ; CHECK-NEXT: .result i32{{$}}
120 ; CHECK-NEXT: .local i32, i32, i32{{$}}
121 ; CHECK-NEXT: i32.or $push, (get_local 0), (get_local 1){{$}}
122 ; CHECK-NEXT: set_local 2, $pop{{$}}
123 ; CHECK-NEXT: return (get_local 2){{$}}
124 define i32 @or32(i32 %x, i32 %y) {
125   %a = or i32 %x, %y
126   ret i32 %a
127 }
128
129 ; CHECK-LABEL: xor32:
130 ; CHECK-NEXT: .param i32{{$}}
131 ; CHECK-NEXT: .param i32{{$}}
132 ; CHECK-NEXT: .result i32{{$}}
133 ; CHECK-NEXT: .local i32, i32, i32{{$}}
134 ; CHECK-NEXT: i32.xor $push, (get_local 0), (get_local 1){{$}}
135 ; CHECK-NEXT: set_local 2, $pop{{$}}
136 ; CHECK-NEXT: return (get_local 2){{$}}
137 define i32 @xor32(i32 %x, i32 %y) {
138   %a = xor i32 %x, %y
139   ret i32 %a
140 }
141
142 ; CHECK-LABEL: shl32:
143 ; CHECK-NEXT: .param i32{{$}}
144 ; CHECK-NEXT: .param i32{{$}}
145 ; CHECK-NEXT: .result i32{{$}}
146 ; CHECK-NEXT: .local i32, i32, i32{{$}}
147 ; CHECK-NEXT: i32.shl $push, (get_local 0), (get_local 1){{$}}
148 ; CHECK-NEXT: set_local 2, $pop{{$}}
149 ; CHECK-NEXT: return (get_local 2){{$}}
150 define i32 @shl32(i32 %x, i32 %y) {
151   %a = shl i32 %x, %y
152   ret i32 %a
153 }
154
155 ; CHECK-LABEL: shr32:
156 ; CHECK-NEXT: .param i32{{$}}
157 ; CHECK-NEXT: .param i32{{$}}
158 ; CHECK-NEXT: .result i32{{$}}
159 ; CHECK-NEXT: .local i32, i32, i32{{$}}
160 ; CHECK-NEXT: i32.shr_u $push, (get_local 0), (get_local 1){{$}}
161 ; CHECK-NEXT: set_local 2, $pop{{$}}
162 ; CHECK-NEXT: return (get_local 2){{$}}
163 define i32 @shr32(i32 %x, i32 %y) {
164   %a = lshr i32 %x, %y
165   ret i32 %a
166 }
167
168 ; CHECK-LABEL: sar32:
169 ; CHECK-NEXT: .param i32{{$}}
170 ; CHECK-NEXT: .param i32{{$}}
171 ; CHECK-NEXT: .result i32{{$}}
172 ; CHECK-NEXT: .local i32, i32, i32{{$}}
173 ; CHECK-NEXT: i32.shr_s $push, (get_local 0), (get_local 1){{$}}
174 ; CHECK-NEXT: set_local 2, $pop{{$}}
175 ; CHECK-NEXT: return (get_local 2){{$}}
176 define i32 @sar32(i32 %x, i32 %y) {
177   %a = ashr i32 %x, %y
178   ret i32 %a
179 }
180
181 ; CHECK-LABEL: clz32:
182 ; CHECK-NEXT: .param i32{{$}}
183 ; CHECK-NEXT: .result i32{{$}}
184 ; CHECK-NEXT: .local i32, i32{{$}}
185 ; CHECK-NEXT: i32.clz $push, (get_local 0){{$}}
186 ; CHECK-NEXT: set_local 1, $pop{{$}}
187 ; CHECK-NEXT: return (get_local 1){{$}}
188 define i32 @clz32(i32 %x) {
189   %a = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
190   ret i32 %a
191 }
192
193 ; CHECK-LABEL: clz32_zero_undef:
194 ; CHECK-NEXT: .param i32{{$}}
195 ; CHECK-NEXT: .result i32{{$}}
196 ; CHECK-NEXT: .local i32, i32{{$}}
197 ; CHECK-NEXT: i32.clz $push, (get_local 0){{$}}
198 ; CHECK-NEXT: set_local 1, $pop{{$}}
199 ; CHECK-NEXT: return (get_local 1){{$}}
200 define i32 @clz32_zero_undef(i32 %x) {
201   %a = call i32 @llvm.ctlz.i32(i32 %x, i1 true)
202   ret i32 %a
203 }
204
205 ; CHECK-LABEL: ctz32:
206 ; CHECK-NEXT: .param i32{{$}}
207 ; CHECK-NEXT: .result i32{{$}}
208 ; CHECK-NEXT: .local i32, i32{{$}}
209 ; CHECK-NEXT: i32.ctz $push, (get_local 0){{$}}
210 ; CHECK-NEXT: set_local 1, $pop{{$}}
211 ; CHECK-NEXT: return (get_local 1){{$}}
212 define i32 @ctz32(i32 %x) {
213   %a = call i32 @llvm.cttz.i32(i32 %x, i1 false)
214   ret i32 %a
215 }
216
217 ; CHECK-LABEL: ctz32_zero_undef:
218 ; CHECK-NEXT: .param i32{{$}}
219 ; CHECK-NEXT: .result i32{{$}}
220 ; CHECK-NEXT: .local i32, i32{{$}}
221 ; CHECK-NEXT: i32.ctz $push, (get_local 0){{$}}
222 ; CHECK-NEXT: set_local 1, $pop{{$}}
223 ; CHECK-NEXT: return (get_local 1){{$}}
224 define i32 @ctz32_zero_undef(i32 %x) {
225   %a = call i32 @llvm.cttz.i32(i32 %x, i1 true)
226   ret i32 %a
227 }
228
229 ; CHECK-LABEL: popcnt32:
230 ; CHECK-NEXT: .param i32{{$}}
231 ; CHECK-NEXT: .result i32{{$}}
232 ; CHECK-NEXT: .local i32, i32{{$}}
233 ; CHECK-NEXT: i32.popcnt $push, (get_local 0){{$}}
234 ; CHECK-NEXT: set_local 1, $pop{{$}}
235 ; CHECK-NEXT: return (get_local 1){{$}}
236 define i32 @popcnt32(i32 %x) {
237   %a = call i32 @llvm.ctpop.i32(i32 %x)
238   ret i32 %a
239 }