...
1;; Test interesting integer "expressions". These tests contain code
2;; patterns which tempt common value-changing optimizations.
3
4;; Test that x+1<y+1 is not folded to x<y.
5
6(module
7 (func (export "i32.no_fold_cmp_s_offset") (param $x i32) (param $y i32) (result i32)
8 (i32.lt_s (i32.add (local.get $x) (i32.const 1)) (i32.add (local.get $y) (i32.const 1))))
9 (func (export "i32.no_fold_cmp_u_offset") (param $x i32) (param $y i32) (result i32)
10 (i32.lt_u (i32.add (local.get $x) (i32.const 1)) (i32.add (local.get $y) (i32.const 1))))
11
12 (func (export "i64.no_fold_cmp_s_offset") (param $x i64) (param $y i64) (result i32)
13 (i64.lt_s (i64.add (local.get $x) (i64.const 1)) (i64.add (local.get $y) (i64.const 1))))
14 (func (export "i64.no_fold_cmp_u_offset") (param $x i64) (param $y i64) (result i32)
15 (i64.lt_u (i64.add (local.get $x) (i64.const 1)) (i64.add (local.get $y) (i64.const 1))))
16)
17
18(assert_return (invoke "i32.no_fold_cmp_s_offset" (i32.const 0x7fffffff) (i32.const 0)) (i32.const 1))
19(assert_return (invoke "i32.no_fold_cmp_u_offset" (i32.const 0xffffffff) (i32.const 0)) (i32.const 1))
20(assert_return (invoke "i64.no_fold_cmp_s_offset" (i64.const 0x7fffffffffffffff) (i64.const 0)) (i32.const 1))
21(assert_return (invoke "i64.no_fold_cmp_u_offset" (i64.const 0xffffffffffffffff) (i64.const 0)) (i32.const 1))
22
23;; Test that wrap(extend_s(x)) is not folded to x.
24
25(module
26 (func (export "i64.no_fold_wrap_extend_s") (param $x i64) (result i64)
27 (i64.extend_i32_s (i32.wrap_i64 (local.get $x))))
28)
29
30(assert_return (invoke "i64.no_fold_wrap_extend_s" (i64.const 0x0010203040506070)) (i64.const 0x0000000040506070))
31(assert_return (invoke "i64.no_fold_wrap_extend_s" (i64.const 0x00a0b0c0d0e0f0a0)) (i64.const 0xffffffffd0e0f0a0))
32
33;; Test that wrap(extend_u(x)) is not folded to x.
34
35(module
36 (func (export "i64.no_fold_wrap_extend_u") (param $x i64) (result i64)
37 (i64.extend_i32_u (i32.wrap_i64 (local.get $x))))
38)
39
40(assert_return (invoke "i64.no_fold_wrap_extend_u" (i64.const 0x0010203040506070)) (i64.const 0x0000000040506070))
41
42;; Test that x<<n>>n is not folded to x.
43
44(module
45 (func (export "i32.no_fold_shl_shr_s") (param $x i32) (result i32)
46 (i32.shr_s (i32.shl (local.get $x) (i32.const 1)) (i32.const 1)))
47 (func (export "i32.no_fold_shl_shr_u") (param $x i32) (result i32)
48 (i32.shr_u (i32.shl (local.get $x) (i32.const 1)) (i32.const 1)))
49
50 (func (export "i64.no_fold_shl_shr_s") (param $x i64) (result i64)
51 (i64.shr_s (i64.shl (local.get $x) (i64.const 1)) (i64.const 1)))
52 (func (export "i64.no_fold_shl_shr_u") (param $x i64) (result i64)
53 (i64.shr_u (i64.shl (local.get $x) (i64.const 1)) (i64.const 1)))
54)
55
56(assert_return (invoke "i32.no_fold_shl_shr_s" (i32.const 0x80000000)) (i32.const 0))
57(assert_return (invoke "i32.no_fold_shl_shr_u" (i32.const 0x80000000)) (i32.const 0))
58(assert_return (invoke "i64.no_fold_shl_shr_s" (i64.const 0x8000000000000000)) (i64.const 0))
59(assert_return (invoke "i64.no_fold_shl_shr_u" (i64.const 0x8000000000000000)) (i64.const 0))
60
61;; Test that x>>n<<n is not folded to x.
62
63(module
64 (func (export "i32.no_fold_shr_s_shl") (param $x i32) (result i32)
65 (i32.shl (i32.shr_s (local.get $x) (i32.const 1)) (i32.const 1)))
66 (func (export "i32.no_fold_shr_u_shl") (param $x i32) (result i32)
67 (i32.shl (i32.shr_u (local.get $x) (i32.const 1)) (i32.const 1)))
68
69 (func (export "i64.no_fold_shr_s_shl") (param $x i64) (result i64)
70 (i64.shl (i64.shr_s (local.get $x) (i64.const 1)) (i64.const 1)))
71 (func (export "i64.no_fold_shr_u_shl") (param $x i64) (result i64)
72 (i64.shl (i64.shr_u (local.get $x) (i64.const 1)) (i64.const 1)))
73)
74
75(assert_return (invoke "i32.no_fold_shr_s_shl" (i32.const 1)) (i32.const 0))
76(assert_return (invoke "i32.no_fold_shr_u_shl" (i32.const 1)) (i32.const 0))
77(assert_return (invoke "i64.no_fold_shr_s_shl" (i64.const 1)) (i64.const 0))
78(assert_return (invoke "i64.no_fold_shr_u_shl" (i64.const 1)) (i64.const 0))
79
80;; Test that x/n*n is not folded to x.
81
82(module
83 (func (export "i32.no_fold_div_s_mul") (param $x i32) (result i32)
84 (i32.mul (i32.div_s (local.get $x) (i32.const 6)) (i32.const 6)))
85 (func (export "i32.no_fold_div_u_mul") (param $x i32) (result i32)
86 (i32.mul (i32.div_u (local.get $x) (i32.const 6)) (i32.const 6)))
87
88 (func (export "i64.no_fold_div_s_mul") (param $x i64) (result i64)
89 (i64.mul (i64.div_s (local.get $x) (i64.const 6)) (i64.const 6)))
90 (func (export "i64.no_fold_div_u_mul") (param $x i64) (result i64)
91 (i64.mul (i64.div_u (local.get $x) (i64.const 6)) (i64.const 6)))
92)
93
94(assert_return (invoke "i32.no_fold_div_s_mul" (i32.const 1)) (i32.const 0))
95(assert_return (invoke "i32.no_fold_div_u_mul" (i32.const 1)) (i32.const 0))
96(assert_return (invoke "i64.no_fold_div_s_mul" (i64.const 1)) (i64.const 0))
97(assert_return (invoke "i64.no_fold_div_u_mul" (i64.const 1)) (i64.const 0))
98
99;; Test that x/x is not folded to 1.
100
101(module
102 (func (export "i32.no_fold_div_s_self") (param $x i32) (result i32)
103 (i32.div_s (local.get $x) (local.get $x)))
104 (func (export "i32.no_fold_div_u_self") (param $x i32) (result i32)
105 (i32.div_u (local.get $x) (local.get $x)))
106
107 (func (export "i64.no_fold_div_s_self") (param $x i64) (result i64)
108 (i64.div_s (local.get $x) (local.get $x)))
109 (func (export "i64.no_fold_div_u_self") (param $x i64) (result i64)
110 (i64.div_u (local.get $x) (local.get $x)))
111)
112
113(assert_trap (invoke "i32.no_fold_div_s_self" (i32.const 0)) "integer divide by zero")
114(assert_trap (invoke "i32.no_fold_div_u_self" (i32.const 0)) "integer divide by zero")
115(assert_trap (invoke "i64.no_fold_div_s_self" (i64.const 0)) "integer divide by zero")
116(assert_trap (invoke "i64.no_fold_div_u_self" (i64.const 0)) "integer divide by zero")
117
118;; Test that x%x is not folded to 0.
119
120(module
121 (func (export "i32.no_fold_rem_s_self") (param $x i32) (result i32)
122 (i32.rem_s (local.get $x) (local.get $x)))
123 (func (export "i32.no_fold_rem_u_self") (param $x i32) (result i32)
124 (i32.rem_u (local.get $x) (local.get $x)))
125
126 (func (export "i64.no_fold_rem_s_self") (param $x i64) (result i64)
127 (i64.rem_s (local.get $x) (local.get $x)))
128 (func (export "i64.no_fold_rem_u_self") (param $x i64) (result i64)
129 (i64.rem_u (local.get $x) (local.get $x)))
130)
131
132(assert_trap (invoke "i32.no_fold_rem_s_self" (i32.const 0)) "integer divide by zero")
133(assert_trap (invoke "i32.no_fold_rem_u_self" (i32.const 0)) "integer divide by zero")
134(assert_trap (invoke "i64.no_fold_rem_s_self" (i64.const 0)) "integer divide by zero")
135(assert_trap (invoke "i64.no_fold_rem_u_self" (i64.const 0)) "integer divide by zero")
136
137;; Test that x*n/n is not folded to x.
138
139(module
140 (func (export "i32.no_fold_mul_div_s") (param $x i32) (result i32)
141 (i32.div_s (i32.mul (local.get $x) (i32.const 6)) (i32.const 6)))
142 (func (export "i32.no_fold_mul_div_u") (param $x i32) (result i32)
143 (i32.div_u (i32.mul (local.get $x) (i32.const 6)) (i32.const 6)))
144
145 (func (export "i64.no_fold_mul_div_s") (param $x i64) (result i64)
146 (i64.div_s (i64.mul (local.get $x) (i64.const 6)) (i64.const 6)))
147 (func (export "i64.no_fold_mul_div_u") (param $x i64) (result i64)
148 (i64.div_u (i64.mul (local.get $x) (i64.const 6)) (i64.const 6)))
149)
150
151(assert_return (invoke "i32.no_fold_mul_div_s" (i32.const 0x80000000)) (i32.const 0))
152(assert_return (invoke "i32.no_fold_mul_div_u" (i32.const 0x80000000)) (i32.const 0))
153(assert_return (invoke "i64.no_fold_mul_div_s" (i64.const 0x8000000000000000)) (i64.const 0))
154(assert_return (invoke "i64.no_fold_mul_div_u" (i64.const 0x8000000000000000)) (i64.const 0))
155
156;; Test that x/n where n is a known power of 2 is not folded to shr_s.
157
158(module
159 (func (export "i32.no_fold_div_s_2") (param $x i32) (result i32)
160 (i32.div_s (local.get $x) (i32.const 2)))
161
162 (func (export "i64.no_fold_div_s_2") (param $x i64) (result i64)
163 (i64.div_s (local.get $x) (i64.const 2)))
164)
165
166(assert_return (invoke "i32.no_fold_div_s_2" (i32.const -11)) (i32.const -5))
167(assert_return (invoke "i64.no_fold_div_s_2" (i64.const -11)) (i64.const -5))
168
169;; Test that x%n where n is a known power of 2 is not folded to and.
170
171(module
172 (func (export "i32.no_fold_rem_s_2") (param $x i32) (result i32)
173 (i32.rem_s (local.get $x) (i32.const 2)))
174
175 (func (export "i64.no_fold_rem_s_2") (param $x i64) (result i64)
176 (i64.rem_s (local.get $x) (i64.const 2)))
177)
178
179(assert_return (invoke "i32.no_fold_rem_s_2" (i32.const -11)) (i32.const -1))
180(assert_return (invoke "i64.no_fold_rem_s_2" (i64.const -11)) (i64.const -1))
181
182;; Test that x/0 works.
183
184(module
185 (func (export "i32.div_s_0") (param $x i32) (result i32)
186 (i32.div_s (local.get $x) (i32.const 0)))
187 (func (export "i32.div_u_0") (param $x i32) (result i32)
188 (i32.div_u (local.get $x) (i32.const 0)))
189
190 (func (export "i64.div_s_0") (param $x i64) (result i64)
191 (i64.div_s (local.get $x) (i64.const 0)))
192 (func (export "i64.div_u_0") (param $x i64) (result i64)
193 (i64.div_u (local.get $x) (i64.const 0)))
194)
195
196(assert_trap (invoke "i32.div_s_0" (i32.const 71)) "integer divide by zero")
197(assert_trap (invoke "i32.div_u_0" (i32.const 71)) "integer divide by zero")
198(assert_trap (invoke "i64.div_s_0" (i64.const 71)) "integer divide by zero")
199(assert_trap (invoke "i64.div_u_0" (i64.const 71)) "integer divide by zero")
200
201;; Test that x/3 works.
202
203(module
204 (func (export "i32.div_s_3") (param $x i32) (result i32)
205 (i32.div_s (local.get $x) (i32.const 3)))
206 (func (export "i32.div_u_3") (param $x i32) (result i32)
207 (i32.div_u (local.get $x) (i32.const 3)))
208
209 (func (export "i64.div_s_3") (param $x i64) (result i64)
210 (i64.div_s (local.get $x) (i64.const 3)))
211 (func (export "i64.div_u_3") (param $x i64) (result i64)
212 (i64.div_u (local.get $x) (i64.const 3)))
213)
214
215(assert_return (invoke "i32.div_s_3" (i32.const 71)) (i32.const 23))
216(assert_return (invoke "i32.div_s_3" (i32.const 0x60000000)) (i32.const 0x20000000))
217(assert_return (invoke "i32.div_u_3" (i32.const 71)) (i32.const 23))
218(assert_return (invoke "i32.div_u_3" (i32.const 0xc0000000)) (i32.const 0x40000000))
219(assert_return (invoke "i64.div_s_3" (i64.const 71)) (i64.const 23))
220(assert_return (invoke "i64.div_s_3" (i64.const 0x3000000000000000)) (i64.const 0x1000000000000000))
221(assert_return (invoke "i64.div_u_3" (i64.const 71)) (i64.const 23))
222(assert_return (invoke "i64.div_u_3" (i64.const 0xc000000000000000)) (i64.const 0x4000000000000000))
223
224;; Test that x/5 works.
225
226(module
227 (func (export "i32.div_s_5") (param $x i32) (result i32)
228 (i32.div_s (local.get $x) (i32.const 5)))
229 (func (export "i32.div_u_5") (param $x i32) (result i32)
230 (i32.div_u (local.get $x) (i32.const 5)))
231
232 (func (export "i64.div_s_5") (param $x i64) (result i64)
233 (i64.div_s (local.get $x) (i64.const 5)))
234 (func (export "i64.div_u_5") (param $x i64) (result i64)
235 (i64.div_u (local.get $x) (i64.const 5)))
236)
237
238(assert_return (invoke "i32.div_s_5" (i32.const 71)) (i32.const 14))
239(assert_return (invoke "i32.div_s_5" (i32.const 0x50000000)) (i32.const 0x10000000))
240(assert_return (invoke "i32.div_u_5" (i32.const 71)) (i32.const 14))
241(assert_return (invoke "i32.div_u_5" (i32.const 0xa0000000)) (i32.const 0x20000000))
242(assert_return (invoke "i64.div_s_5" (i64.const 71)) (i64.const 14))
243(assert_return (invoke "i64.div_s_5" (i64.const 0x5000000000000000)) (i64.const 0x1000000000000000))
244(assert_return (invoke "i64.div_u_5" (i64.const 71)) (i64.const 14))
245(assert_return (invoke "i64.div_u_5" (i64.const 0xa000000000000000)) (i64.const 0x2000000000000000))
246
247;; Test that x/7 works.
248
249(module
250 (func (export "i32.div_s_7") (param $x i32) (result i32)
251 (i32.div_s (local.get $x) (i32.const 7)))
252 (func (export "i32.div_u_7") (param $x i32) (result i32)
253 (i32.div_u (local.get $x) (i32.const 7)))
254
255 (func (export "i64.div_s_7") (param $x i64) (result i64)
256 (i64.div_s (local.get $x) (i64.const 7)))
257 (func (export "i64.div_u_7") (param $x i64) (result i64)
258 (i64.div_u (local.get $x) (i64.const 7)))
259)
260
261(assert_return (invoke "i32.div_s_7" (i32.const 71)) (i32.const 10))
262(assert_return (invoke "i32.div_s_7" (i32.const 0x70000000)) (i32.const 0x10000000))
263(assert_return (invoke "i32.div_u_7" (i32.const 71)) (i32.const 10))
264(assert_return (invoke "i32.div_u_7" (i32.const 0xe0000000)) (i32.const 0x20000000))
265(assert_return (invoke "i64.div_s_7" (i64.const 71)) (i64.const 10))
266(assert_return (invoke "i64.div_s_7" (i64.const 0x7000000000000000)) (i64.const 0x1000000000000000))
267(assert_return (invoke "i64.div_u_7" (i64.const 71)) (i64.const 10))
268(assert_return (invoke "i64.div_u_7" (i64.const 0xe000000000000000)) (i64.const 0x2000000000000000))
269
270;; Test that x%3 works.
271
272(module
273 (func (export "i32.rem_s_3") (param $x i32) (result i32)
274 (i32.rem_s (local.get $x) (i32.const 3)))
275 (func (export "i32.rem_u_3") (param $x i32) (result i32)
276 (i32.rem_u (local.get $x) (i32.const 3)))
277
278 (func (export "i64.rem_s_3") (param $x i64) (result i64)
279 (i64.rem_s (local.get $x) (i64.const 3)))
280 (func (export "i64.rem_u_3") (param $x i64) (result i64)
281 (i64.rem_u (local.get $x) (i64.const 3)))
282)
283
284(assert_return (invoke "i32.rem_s_3" (i32.const 71)) (i32.const 2))
285(assert_return (invoke "i32.rem_s_3" (i32.const 0x60000000)) (i32.const 0))
286(assert_return (invoke "i32.rem_u_3" (i32.const 71)) (i32.const 2))
287(assert_return (invoke "i32.rem_u_3" (i32.const 0xc0000000)) (i32.const 0))
288(assert_return (invoke "i64.rem_s_3" (i64.const 71)) (i64.const 2))
289(assert_return (invoke "i64.rem_s_3" (i64.const 0x3000000000000000)) (i64.const 0))
290(assert_return (invoke "i64.rem_u_3" (i64.const 71)) (i64.const 2))
291(assert_return (invoke "i64.rem_u_3" (i64.const 0xc000000000000000)) (i64.const 0))
292
293;; Test that x%5 works.
294
295(module
296 (func (export "i32.rem_s_5") (param $x i32) (result i32)
297 (i32.rem_s (local.get $x) (i32.const 5)))
298 (func (export "i32.rem_u_5") (param $x i32) (result i32)
299 (i32.rem_u (local.get $x) (i32.const 5)))
300
301 (func (export "i64.rem_s_5") (param $x i64) (result i64)
302 (i64.rem_s (local.get $x) (i64.const 5)))
303 (func (export "i64.rem_u_5") (param $x i64) (result i64)
304 (i64.rem_u (local.get $x) (i64.const 5)))
305)
306
307(assert_return (invoke "i32.rem_s_5" (i32.const 71)) (i32.const 1))
308(assert_return (invoke "i32.rem_s_5" (i32.const 0x50000000)) (i32.const 0))
309(assert_return (invoke "i32.rem_u_5" (i32.const 71)) (i32.const 1))
310(assert_return (invoke "i32.rem_u_5" (i32.const 0xa0000000)) (i32.const 0))
311(assert_return (invoke "i64.rem_s_5" (i64.const 71)) (i64.const 1))
312(assert_return (invoke "i64.rem_s_5" (i64.const 0x5000000000000000)) (i64.const 0))
313(assert_return (invoke "i64.rem_u_5" (i64.const 71)) (i64.const 1))
314(assert_return (invoke "i64.rem_u_5" (i64.const 0xa000000000000000)) (i64.const 0))
315
316;; Test that x%7 works.
317
318(module
319 (func (export "i32.rem_s_7") (param $x i32) (result i32)
320 (i32.rem_s (local.get $x) (i32.const 7)))
321 (func (export "i32.rem_u_7") (param $x i32) (result i32)
322 (i32.rem_u (local.get $x) (i32.const 7)))
323
324 (func (export "i64.rem_s_7") (param $x i64) (result i64)
325 (i64.rem_s (local.get $x) (i64.const 7)))
326 (func (export "i64.rem_u_7") (param $x i64) (result i64)
327 (i64.rem_u (local.get $x) (i64.const 7)))
328)
329
330(assert_return (invoke "i32.rem_s_7" (i32.const 71)) (i32.const 1))
331(assert_return (invoke "i32.rem_s_7" (i32.const 0x70000000)) (i32.const 0))
332(assert_return (invoke "i32.rem_u_7" (i32.const 71)) (i32.const 1))
333(assert_return (invoke "i32.rem_u_7" (i32.const 0xe0000000)) (i32.const 0))
334(assert_return (invoke "i64.rem_s_7" (i64.const 71)) (i64.const 1))
335(assert_return (invoke "i64.rem_s_7" (i64.const 0x7000000000000000)) (i64.const 0))
336(assert_return (invoke "i64.rem_u_7" (i64.const 71)) (i64.const 1))
337(assert_return (invoke "i64.rem_u_7" (i64.const 0xe000000000000000)) (i64.const 0))
338
339;; Test that x/-1 is not folded to -x.
340
341(module
342 (func (export "i32.no_fold_div_neg1") (param $x i32) (result i32)
343 (i32.div_s (local.get $x) (i32.const -1)))
344
345 (func (export "i64.no_fold_div_neg1") (param $x i64) (result i64)
346 (i64.div_s (local.get $x) (i64.const -1)))
347)
348
349(assert_trap (invoke "i32.no_fold_div_neg1" (i32.const 0x80000000)) "integer overflow")
350(assert_trap (invoke "i64.no_fold_div_neg1" (i64.const 0x8000000000000000)) "integer overflow")
View as plain text