github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/integration_test/spectest/v1/testdata/int_exprs.wast (about) 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")