github.com/tetratelabs/wazero@v1.7.1/internal/engine/wazevo/frontend/frontend_test.go (about) 1 package frontend 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/tetratelabs/wazero/api" 8 "github.com/tetratelabs/wazero/experimental" 9 "github.com/tetratelabs/wazero/internal/engine/wazevo/ssa" 10 "github.com/tetratelabs/wazero/internal/engine/wazevo/testcases" 11 "github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi" 12 "github.com/tetratelabs/wazero/internal/testing/require" 13 "github.com/tetratelabs/wazero/internal/wasm" 14 ) 15 16 func TestCompiler_LowerToSSA(t *testing.T) { 17 // Most of the logic should look similar to Cranelift's Wasm frontend, so when you want to see 18 // what output should look like, you can run: 19 // `~/wasmtime/target/debug/clif-util wasm --target aarch64-apple-darwin testcase.wat -p -t` 20 for _, tc := range []struct { 21 name string 22 ensureTermination bool 23 needListener bool 24 // m is the *wasm.Module to be compiled in this test. 25 m *wasm.Module 26 // targetIndex is the index of a local function to be compiled in this test. 27 targetIndex wasm.Index 28 // exp is the *unoptimized* expected SSA IR for the function m.FunctionSection[targetIndex]. 29 exp string 30 // expAfterPasses is not empty when we want to check the result after SSA passes. 31 expAfterPasses string 32 features api.CoreFeatures 33 }{ 34 { 35 name: "empty", m: testcases.Empty.Module, 36 exp: ` 37 blk0: (exec_ctx:i64, module_ctx:i64) 38 Jump blk_ret 39 `, 40 }, 41 { 42 name: "unreachable", m: testcases.Unreachable.Module, 43 exp: ` 44 blk0: (exec_ctx:i64, module_ctx:i64) 45 Exit exec_ctx, unreachable 46 `, 47 }, 48 { 49 name: testcases.OnlyReturn.Name, m: testcases.OnlyReturn.Module, 50 exp: ` 51 blk0: (exec_ctx:i64, module_ctx:i64) 52 Return 53 `, 54 }, 55 { 56 name: "params", m: testcases.Params.Module, 57 exp: ` 58 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:f32, v4:f64) 59 Return 60 `, 61 }, 62 { 63 name: "add/sub params return", m: testcases.AddSubParamsReturn.Module, 64 exp: ` 65 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 66 v4:i32 = Iadd v2, v3 67 v5:i32 = Isub v4, v2 68 Jump blk_ret, v5 69 `, 70 }, 71 { 72 name: "add/sub params return / listener", m: testcases.AddSubParamsReturn.Module, 73 needListener: true, 74 exp: ` 75 signatures: 76 sig1: i64i32i32i32_v 77 sig2: i64i32i32_v 78 79 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 80 Store module_ctx, exec_ctx, 0x8 81 v4:i64 = Load module_ctx, 0x8 82 v5:i64 = Load v4, 0x0 83 v6:i32 = Iconst_32 0x0 84 CallIndirect v5:sig1, exec_ctx, v6, v2, v3 85 v7:i32 = Iadd v2, v3 86 v8:i32 = Isub v7, v2 87 Store module_ctx, exec_ctx, 0x8 88 v9:i64 = Load module_ctx, 0x10 89 v10:i64 = Load v9, 0x0 90 v11:i32 = Iconst_32 0x0 91 CallIndirect v10:sig2, exec_ctx, v11, v8 92 Jump blk_ret, v8 93 `, 94 }, 95 { 96 name: "locals", m: testcases.Locals.Module, 97 exp: ` 98 blk0: (exec_ctx:i64, module_ctx:i64) 99 v2:i32 = Iconst_32 0x0 100 v3:i64 = Iconst_64 0x0 101 v4:f32 = F32const 0.000000 102 v5:f64 = F64const 0.000000 103 Jump blk_ret 104 `, 105 expAfterPasses: ` 106 blk0: (exec_ctx:i64, module_ctx:i64) 107 Jump blk_ret 108 `, 109 }, 110 { 111 name: "selects", m: testcases.Selects.Module, 112 exp: ` 113 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i64, v5:i64, v6:f32, v7:f32, v8:f64, v9:f64) 114 v10:i32 = Icmp eq, v4, v5 115 v11:i32 = Select v10, v2, v3 116 v12:i64 = Select v3, v4, v5 117 v13:i32 = Fcmp gt, v8, v9 118 v14:f32 = Select v13, v6, v7 119 v15:i32 = Fcmp neq, v6, v7 120 v16:f64 = Select v15, v8, v9 121 Jump blk_ret, v11, v12, v14, v16 122 `, 123 }, 124 { 125 name: "local param tee return", m: testcases.LocalParamTeeReturn.Module, 126 exp: ` 127 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 128 v3:i32 = Iconst_32 0x0 129 Jump blk_ret, v2, v2 130 `, 131 expAfterPasses: ` 132 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 133 Jump blk_ret, v2, v2 134 `, 135 }, 136 { 137 name: "locals + params", m: testcases.LocalsParams.Module, 138 exp: ` 139 blk0: (exec_ctx:i64, module_ctx:i64, v2:i64, v3:f32, v4:f64) 140 v5:i32 = Iconst_32 0x0 141 v6:i64 = Iconst_64 0x0 142 v7:f32 = F32const 0.000000 143 v8:f64 = F64const 0.000000 144 v9:i64 = Iadd v2, v2 145 v10:i64 = Isub v9, v2 146 v11:f32 = Fadd v3, v3 147 v12:f32 = Fsub v11, v3 148 v13:f32 = Fmul v12, v3 149 v14:f32 = Fdiv v13, v3 150 v15:f32 = Fmax v14, v3 151 v16:f32 = Fmin v15, v3 152 v17:f64 = Fadd v4, v4 153 v18:f64 = Fsub v17, v4 154 v19:f64 = Fmul v18, v4 155 v20:f64 = Fdiv v19, v4 156 v21:f64 = Fmax v20, v4 157 v22:f64 = Fmin v21, v4 158 Jump blk_ret, v10, v16, v22 159 `, 160 expAfterPasses: ` 161 blk0: (exec_ctx:i64, module_ctx:i64, v2:i64, v3:f32, v4:f64) 162 v9:i64 = Iadd v2, v2 163 v10:i64 = Isub v9, v2 164 v11:f32 = Fadd v3, v3 165 v12:f32 = Fsub v11, v3 166 v13:f32 = Fmul v12, v3 167 v14:f32 = Fdiv v13, v3 168 v15:f32 = Fmax v14, v3 169 v16:f32 = Fmin v15, v3 170 v17:f64 = Fadd v4, v4 171 v18:f64 = Fsub v17, v4 172 v19:f64 = Fmul v18, v4 173 v20:f64 = Fdiv v19, v4 174 v21:f64 = Fmax v20, v4 175 v22:f64 = Fmin v21, v4 176 Jump blk_ret, v10, v16, v22 177 `, 178 }, 179 { 180 name: "locals + params + return", m: testcases.LocalParamReturn.Module, 181 exp: ` 182 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 183 v3:i32 = Iconst_32 0x0 184 Jump blk_ret, v2, v3 185 `, 186 }, 187 { 188 name: "swap param and return", m: testcases.SwapParamAndReturn.Module, 189 exp: ` 190 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 191 Jump blk_ret, v3, v2 192 `, 193 }, 194 { 195 name: "swap params and return", m: testcases.SwapParamsAndReturn.Module, 196 exp: ` 197 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 198 Jump blk1 199 200 blk1: () <-- (blk0) 201 Jump blk_ret, v3, v2 202 `, 203 }, 204 { 205 name: "block - br", m: testcases.BlockBr.Module, 206 exp: ` 207 blk0: (exec_ctx:i64, module_ctx:i64) 208 v2:i32 = Iconst_32 0x0 209 v3:i64 = Iconst_64 0x0 210 v4:f32 = F32const 0.000000 211 v5:f64 = F64const 0.000000 212 Jump blk1 213 214 blk1: () <-- (blk0) 215 Jump blk_ret 216 `, 217 }, 218 { 219 name: "block - br_if", m: testcases.BlockBrIf.Module, 220 exp: ` 221 blk0: (exec_ctx:i64, module_ctx:i64) 222 v2:i32 = Iconst_32 0x0 223 Brnz v2, blk1 224 Jump blk2 225 226 blk1: () <-- (blk0) 227 Jump blk_ret 228 229 blk2: () <-- (blk0) 230 Exit exec_ctx, unreachable 231 `, 232 }, 233 { 234 name: "loop - br", m: testcases.LoopBr.Module, 235 exp: ` 236 blk0: (exec_ctx:i64, module_ctx:i64) 237 Jump blk1 238 239 blk1: () <-- (blk0,blk1) 240 Jump blk1 241 242 blk2: () 243 `, 244 expAfterPasses: ` 245 blk0: (exec_ctx:i64, module_ctx:i64) 246 Jump fallthrough 247 248 blk1: () <-- (blk0,blk1) 249 Jump blk1 250 `, 251 }, 252 { 253 name: "loop - br / ensure termination", m: testcases.LoopBr.Module, 254 ensureTermination: true, 255 exp: ` 256 signatures: 257 sig2: i64_v 258 259 blk0: (exec_ctx:i64, module_ctx:i64) 260 Jump blk1 261 262 blk1: () <-- (blk0,blk1) 263 v2:i64 = Load exec_ctx, 0x58 264 CallIndirect v2:sig2, exec_ctx 265 Jump blk1 266 267 blk2: () 268 `, 269 expAfterPasses: ` 270 signatures: 271 sig2: i64_v 272 273 blk0: (exec_ctx:i64, module_ctx:i64) 274 Jump fallthrough 275 276 blk1: () <-- (blk0,blk1) 277 v2:i64 = Load exec_ctx, 0x58 278 CallIndirect v2:sig2, exec_ctx 279 Jump blk1 280 `, 281 }, 282 { 283 name: "loop - br_if", m: testcases.LoopBrIf.Module, 284 exp: ` 285 blk0: (exec_ctx:i64, module_ctx:i64) 286 Jump blk1 287 288 blk1: () <-- (blk0,blk1) 289 v2:i32 = Iconst_32 0x1 290 Brnz v2, blk1 291 Jump blk3 292 293 blk2: () 294 295 blk3: () <-- (blk1) 296 Return 297 `, 298 expAfterPasses: ` 299 blk0: (exec_ctx:i64, module_ctx:i64) 300 Jump fallthrough 301 302 blk1: () <-- (blk0,blk4) 303 v2:i32 = Iconst_32 0x1 304 Brz v2, blk3 305 Jump fallthrough 306 307 blk4: () <-- (blk1) 308 Jump blk1 309 310 blk3: () <-- (blk1) 311 Return 312 `, 313 }, 314 { 315 name: "block - block - br", m: testcases.BlockBlockBr.Module, 316 exp: ` 317 blk0: (exec_ctx:i64, module_ctx:i64) 318 v2:i32 = Iconst_32 0x0 319 v3:i64 = Iconst_64 0x0 320 v4:f32 = F32const 0.000000 321 v5:f64 = F64const 0.000000 322 Jump blk1 323 324 blk1: () <-- (blk0) 325 Jump blk_ret 326 327 blk2: () 328 `, 329 expAfterPasses: ` 330 blk0: (exec_ctx:i64, module_ctx:i64) 331 Jump fallthrough 332 333 blk1: () <-- (blk0) 334 Jump blk_ret 335 `, 336 }, 337 { 338 name: "if without else", m: testcases.IfWithoutElse.Module, 339 exp: ` 340 blk0: (exec_ctx:i64, module_ctx:i64) 341 v2:i32 = Iconst_32 0x0 342 Brz v2, blk2 343 Jump blk1 344 345 blk1: () <-- (blk0) 346 Jump blk3 347 348 blk2: () <-- (blk0) 349 Jump blk3 350 351 blk3: () <-- (blk1,blk2) 352 Jump blk_ret 353 `, 354 }, 355 { 356 name: "if-else", m: testcases.IfElse.Module, 357 exp: ` 358 blk0: (exec_ctx:i64, module_ctx:i64) 359 v2:i32 = Iconst_32 0x0 360 Brz v2, blk2 361 Jump blk1 362 363 blk1: () <-- (blk0) 364 Jump blk3 365 366 blk2: () <-- (blk0) 367 Jump blk_ret 368 369 blk3: () <-- (blk1) 370 Jump blk_ret 371 `, 372 }, 373 { 374 name: "single predecessor local refs", m: testcases.SinglePredecessorLocalRefs.Module, 375 exp: ` 376 blk0: (exec_ctx:i64, module_ctx:i64) 377 v2:i32 = Iconst_32 0x0 378 v3:i32 = Iconst_32 0x0 379 v4:i32 = Iconst_32 0x0 380 Brz v2, blk2 381 Jump blk1 382 383 blk1: () <-- (blk0) 384 Return v4 385 386 blk2: () <-- (blk0) 387 Jump blk3 388 389 blk3: () <-- (blk2) 390 Jump blk_ret, v2 391 `, 392 expAfterPasses: ` 393 blk0: (exec_ctx:i64, module_ctx:i64) 394 v2:i32 = Iconst_32 0x0 395 v4:i32 = Iconst_32 0x0 396 Brz v2, blk2 397 Jump fallthrough 398 399 blk1: () <-- (blk0) 400 Return v4 401 402 blk2: () <-- (blk0) 403 Jump fallthrough 404 405 blk3: () <-- (blk2) 406 Jump blk_ret, v2 407 `, 408 }, 409 { 410 name: "multi predecessors local ref", 411 m: testcases.MultiPredecessorLocalRef.Module, 412 exp: ` 413 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 414 v4:i32 = Iconst_32 0x0 415 Brz v2, blk2 416 Jump blk1 417 418 blk1: () <-- (blk0) 419 Jump blk3, v2 420 421 blk2: () <-- (blk0) 422 Jump blk3, v3 423 424 blk3: (v5:i32) <-- (blk1,blk2) 425 Jump blk_ret, v5 426 `, 427 expAfterPasses: ` 428 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 429 Brz v2, blk2 430 Jump fallthrough 431 432 blk1: () <-- (blk0) 433 Jump blk3, v2 434 435 blk2: () <-- (blk0) 436 Jump fallthrough, v3 437 438 blk3: (v5:i32) <-- (blk1,blk2) 439 Jump blk_ret, v5 440 `, 441 }, 442 { 443 name: "reference value from unsealed block", 444 m: testcases.ReferenceValueFromUnsealedBlock.Module, 445 exp: ` 446 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 447 v3:i32 = Iconst_32 0x0 448 Jump blk1 449 450 blk1: () <-- (blk0) 451 Return v2 452 453 blk2: () 454 `, 455 expAfterPasses: ` 456 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 457 Jump fallthrough 458 459 blk1: () <-- (blk0) 460 Return v2 461 `, 462 }, 463 { 464 name: "reference value from unsealed block - #2", 465 m: testcases.ReferenceValueFromUnsealedBlock2.Module, 466 exp: ` 467 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 468 Jump blk1 469 470 blk1: () <-- (blk0,blk1) 471 Brnz v2, blk1 472 Jump blk4 473 474 blk2: () <-- (blk3) 475 v3:i32 = Iconst_32 0x0 476 Jump blk_ret, v3 477 478 blk3: () <-- (blk4) 479 Jump blk2 480 481 blk4: () <-- (blk1) 482 Jump blk3 483 `, 484 expAfterPasses: ` 485 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 486 Jump fallthrough 487 488 blk1: () <-- (blk0,blk5) 489 Brz v2, blk4 490 Jump fallthrough 491 492 blk5: () <-- (blk1) 493 Jump blk1 494 495 blk4: () <-- (blk1) 496 Jump fallthrough 497 498 blk3: () <-- (blk4) 499 Jump fallthrough 500 501 blk2: () <-- (blk3) 502 v3:i32 = Iconst_32 0x0 503 Jump blk_ret, v3 504 `, 505 }, 506 { 507 name: "reference value from unsealed block - #3", 508 m: testcases.ReferenceValueFromUnsealedBlock3.Module, 509 exp: ` 510 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 511 Jump blk1, v2 512 513 blk1: (v3:i32) <-- (blk0,blk3) 514 Brnz v3, blk_ret 515 Jump blk4 516 517 blk2: () 518 519 blk3: () <-- (blk4) 520 v4:i32 = Iconst_32 0x1 521 Jump blk1, v4 522 523 blk4: () <-- (blk1) 524 Jump blk3 525 `, 526 expAfterPasses: ` 527 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 528 Jump fallthrough, v2 529 530 blk1: (v3:i32) <-- (blk0,blk3) 531 Brnz v3, blk5 532 Jump blk4 533 534 blk5: () <-- (blk1) 535 Jump blk_ret 536 537 blk4: () <-- (blk1) 538 Jump fallthrough 539 540 blk3: () <-- (blk4) 541 v4:i32 = Iconst_32 0x1 542 Jump blk1, v4 543 `, 544 }, 545 { 546 name: "call", 547 m: testcases.Call.Module, 548 exp: ` 549 signatures: 550 sig1: i64i64_i32 551 sig2: i64i64i32i32_i32 552 sig3: i64i64i32_i32i32 553 554 blk0: (exec_ctx:i64, module_ctx:i64) 555 v2:i32 = Call f1:sig1, exec_ctx, module_ctx 556 v3:i32 = Iconst_32 0x5 557 v4:i32 = Call f2:sig2, exec_ctx, module_ctx, v2, v3 558 v5:i32, v6:i32 = Call f3:sig3, exec_ctx, module_ctx, v4 559 Jump blk_ret, v5, v6 560 `, 561 }, 562 { 563 name: "call_many_params", 564 m: testcases.CallManyParams.Module, 565 exp: ` 566 signatures: 567 sig1: i64i64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64_v 568 569 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i64, v4:f32, v5:f64) 570 Call f1:sig1, exec_ctx, module_ctx, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5 571 Jump blk_ret 572 `, 573 }, 574 { 575 name: "call_many_returns", 576 m: testcases.CallManyReturns.Module, 577 exp: ` 578 signatures: 579 sig0: i64i64i32i64f32f64_i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64i32i64f32f64 580 581 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i64, v4:f32, v5:f64) 582 v6:i32, v7:i64, v8:f32, v9:f64, v10:i32, v11:i64, v12:f32, v13:f64, v14:i32, v15:i64, v16:f32, v17:f64, v18:i32, v19:i64, v20:f32, v21:f64, v22:i32, v23:i64, v24:f32, v25:f64, v26:i32, v27:i64, v28:f32, v29:f64, v30:i32, v31:i64, v32:f32, v33:f64, v34:i32, v35:i64, v36:f32, v37:f64, v38:i32, v39:i64, v40:f32, v41:f64, v42:i32, v43:i64, v44:f32, v45:f64 = Call f1:sig0, exec_ctx, module_ctx, v2, v3, v4, v5 583 Jump blk_ret, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45 584 `, 585 }, 586 { 587 name: "integer comparisons", m: testcases.IntegerComparisons.Module, 588 exp: ` 589 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i64, v5:i64) 590 v6:i32 = Icmp eq, v2, v3 591 v7:i32 = Icmp eq, v4, v5 592 v8:i32 = Icmp neq, v2, v3 593 v9:i32 = Icmp neq, v4, v5 594 v10:i32 = Icmp lt_s, v2, v3 595 v11:i32 = Icmp lt_s, v4, v5 596 v12:i32 = Icmp lt_u, v2, v3 597 v13:i32 = Icmp lt_u, v4, v5 598 v14:i32 = Icmp gt_s, v2, v3 599 v15:i32 = Icmp gt_s, v4, v5 600 v16:i32 = Icmp gt_u, v2, v3 601 v17:i32 = Icmp gt_u, v4, v5 602 v18:i32 = Icmp le_s, v2, v3 603 v19:i32 = Icmp le_s, v4, v5 604 v20:i32 = Icmp le_u, v2, v3 605 v21:i32 = Icmp le_u, v4, v5 606 v22:i32 = Icmp ge_s, v2, v3 607 v23:i32 = Icmp ge_s, v4, v5 608 v24:i32 = Icmp ge_u, v2, v3 609 v25:i32 = Icmp ge_u, v4, v5 610 Jump blk_ret, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25 611 `, 612 expAfterPasses: ` 613 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i64, v5:i64) 614 v6:i32 = Icmp eq, v2, v3 615 v7:i32 = Icmp eq, v4, v5 616 v8:i32 = Icmp neq, v2, v3 617 v9:i32 = Icmp neq, v4, v5 618 v10:i32 = Icmp lt_s, v2, v3 619 v11:i32 = Icmp lt_s, v4, v5 620 v12:i32 = Icmp lt_u, v2, v3 621 v13:i32 = Icmp lt_u, v4, v5 622 v14:i32 = Icmp gt_s, v2, v3 623 v15:i32 = Icmp gt_s, v4, v5 624 v16:i32 = Icmp gt_u, v2, v3 625 v17:i32 = Icmp gt_u, v4, v5 626 v18:i32 = Icmp le_s, v2, v3 627 v19:i32 = Icmp le_s, v4, v5 628 v20:i32 = Icmp le_u, v2, v3 629 v21:i32 = Icmp le_u, v4, v5 630 v22:i32 = Icmp ge_s, v2, v3 631 v23:i32 = Icmp ge_s, v4, v5 632 v24:i32 = Icmp ge_u, v2, v3 633 v25:i32 = Icmp ge_u, v4, v5 634 Jump blk_ret, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25 635 `, 636 }, 637 { 638 name: "integer bitwise", m: testcases.IntegerBitwise.Module, 639 exp: ` 640 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i64, v5:i64) 641 v6:i32 = Band v2, v3 642 v7:i32 = Bor v2, v3 643 v8:i32 = Bxor v2, v3 644 v9:i32 = Rotr v2, v3 645 v10:i64 = Band v4, v5 646 v11:i64 = Bor v4, v5 647 v12:i64 = Bxor v4, v5 648 v13:i64 = Iconst_64 0x8 649 v14:i64 = Ishl v5, v13 650 v15:i64 = Bxor v4, v14 651 v16:i64 = Rotl v4, v5 652 v17:i64 = Rotr v4, v5 653 Jump blk_ret, v6, v7, v8, v9, v10, v11, v12, v15, v16, v17 654 `, 655 }, 656 { 657 name: "integer shift", m: testcases.IntegerShift.Module, 658 exp: ` 659 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i64, v5:i64) 660 v6:i32 = Ishl v2, v3 661 v7:i32 = Iconst_32 0x1f 662 v8:i32 = Ishl v2, v7 663 v9:i64 = Ishl v4, v5 664 v10:i64 = Iconst_64 0x20 665 v11:i64 = Ishl v4, v10 666 v12:i32 = Ushr v2, v3 667 v13:i32 = Iconst_32 0x1f 668 v14:i32 = Ushr v2, v13 669 v15:i64 = Ushr v4, v5 670 v16:i64 = Iconst_64 0x20 671 v17:i64 = Ushr v4, v16 672 v18:i32 = Sshr v2, v3 673 v19:i32 = Iconst_32 0x1f 674 v20:i32 = Sshr v2, v19 675 v21:i64 = Sshr v4, v5 676 v22:i64 = Iconst_64 0x20 677 v23:i64 = Sshr v4, v22 678 Jump blk_ret, v6, v8, v9, v11, v12, v14, v15, v17, v18, v20, v21, v23 679 `, 680 }, 681 { 682 name: "integer extension", m: testcases.IntegerExtensions.Module, 683 exp: ` 684 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i64) 685 v4:i64 = SExtend v2, 32->64 686 v5:i64 = UExtend v2, 32->64 687 v6:i64 = SExtend v3, 8->64 688 v7:i64 = SExtend v3, 16->64 689 v8:i64 = SExtend v3, 32->64 690 v9:i32 = SExtend v2, 8->32 691 v10:i32 = SExtend v2, 16->32 692 Jump blk_ret, v4, v5, v6, v7, v8, v9, v10 693 `, 694 }, 695 { 696 name: "integer bit counts", m: testcases.IntegerBitCounts.Module, 697 exp: ` 698 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i64) 699 v4:i32 = Clz v2 700 v5:i32 = Ctz v2 701 v6:i32 = Popcnt v2 702 v7:i64 = Clz v3 703 v8:i64 = Ctz v3 704 v9:i64 = Popcnt v3 705 Jump blk_ret, v4, v5, v6, v7, v8, v9 706 `, 707 }, 708 { 709 name: "float comparisons", m: testcases.FloatComparisons.Module, 710 exp: ` 711 blk0: (exec_ctx:i64, module_ctx:i64, v2:f32, v3:f32, v4:f64, v5:f64) 712 v6:i32 = Fcmp eq, v2, v3 713 v7:i32 = Fcmp neq, v2, v3 714 v8:i32 = Fcmp lt, v2, v3 715 v9:i32 = Fcmp gt, v2, v3 716 v10:i32 = Fcmp le, v2, v3 717 v11:i32 = Fcmp ge, v2, v3 718 v12:i32 = Fcmp eq, v4, v5 719 v13:i32 = Fcmp neq, v4, v5 720 v14:i32 = Fcmp lt, v4, v5 721 v15:i32 = Fcmp gt, v4, v5 722 v16:i32 = Fcmp le, v4, v5 723 v17:i32 = Fcmp ge, v4, v5 724 Jump blk_ret, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17 725 `, 726 }, 727 { 728 name: "float conversions", m: testcases.FloatConversions.Module, 729 exp: ` 730 blk0: (exec_ctx:i64, module_ctx:i64, v2:f64, v3:f32) 731 v4:i64 = FcvtToSint v2 732 v5:i64 = FcvtToSint v3 733 v6:i32 = FcvtToSint v2 734 v7:i32 = FcvtToSint v3 735 v8:i64 = FcvtToUint v2 736 v9:i64 = FcvtToUint v3 737 v10:i32 = FcvtToUint v2 738 v11:i32 = FcvtToUint v3 739 v12:f32 = Fdemote v2 740 v13:f64 = Fpromote v3 741 Jump blk_ret, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 742 `, 743 }, 744 { 745 name: "non-trapping float conversions", m: testcases.NonTrappingFloatConversions.Module, 746 exp: ` 747 blk0: (exec_ctx:i64, module_ctx:i64, v2:f64, v3:f32) 748 v4:i64 = FcvtToSintSat v2 749 v5:i64 = FcvtToSintSat v3 750 v6:i32 = FcvtToSintSat v2 751 v7:i32 = FcvtToSintSat v3 752 v8:i64 = FcvtToUintSat v2 753 v9:i64 = FcvtToUintSat v3 754 v10:i32 = FcvtToUintSat v2 755 v11:i32 = FcvtToUintSat v3 756 Jump blk_ret, v4, v5, v6, v7, v8, v9, v10, v11 757 `, 758 }, 759 { 760 name: "loop with param and results", m: testcases.LoopBrWithParamResults.Module, 761 exp: ` 762 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 763 Jump blk1, v2, v3 764 765 blk1: (v4:i32,v5:i32) <-- (blk0,blk1) 766 v7:i32 = Iconst_32 0x1 767 Brnz v7, blk1, v4, v5 768 Jump blk3 769 770 blk2: (v6:i32) <-- (blk3) 771 Jump blk_ret, v6 772 773 blk3: () <-- (blk1) 774 Jump blk2, v4 775 `, 776 expAfterPasses: ` 777 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 778 Jump fallthrough 779 780 blk1: () <-- (blk0,blk4) 781 v7:i32 = Iconst_32 0x1 782 Brz v7, blk3 783 Jump fallthrough 784 785 blk4: () <-- (blk1) 786 Jump blk1 787 788 blk3: () <-- (blk1) 789 Jump fallthrough 790 791 blk2: () <-- (blk3) 792 Jump blk_ret, v2 793 `, 794 }, 795 { 796 name: "many_params_small_results", 797 m: testcases.ManyParamsSmallResults.Module, 798 targetIndex: 0, 799 exp: ` 800 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i64, v4:f32, v5:f64, v6:i32, v7:i64, v8:f32, v9:f64, v10:i32, v11:i64, v12:f32, v13:f64, v14:i32, v15:i64, v16:f32, v17:f64, v18:i32, v19:i64, v20:f32, v21:f64, v22:i32, v23:i64, v24:f32, v25:f64, v26:i32, v27:i64, v28:f32, v29:f64, v30:i32, v31:i64, v32:f32, v33:f64, v34:i32, v35:i64, v36:f32, v37:f64, v38:i32, v39:i64, v40:f32, v41:f64) 801 Jump blk_ret, v2, v11, v20, v29 802 `, 803 expAfterPasses: ` 804 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i64, v4:f32, v5:f64, v6:i32, v7:i64, v8:f32, v9:f64, v10:i32, v11:i64, v12:f32, v13:f64, v14:i32, v15:i64, v16:f32, v17:f64, v18:i32, v19:i64, v20:f32, v21:f64, v22:i32, v23:i64, v24:f32, v25:f64, v26:i32, v27:i64, v28:f32, v29:f64, v30:i32, v31:i64, v32:f32, v33:f64, v34:i32, v35:i64, v36:f32, v37:f64, v38:i32, v39:i64, v40:f32, v41:f64) 805 Jump blk_ret, v2, v11, v20, v29 806 `, 807 }, 808 { 809 name: "small_params_many_results", 810 m: testcases.SmallParamsManyResults.Module, 811 targetIndex: 0, 812 exp: ` 813 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i64, v4:f32, v5:f64) 814 Jump blk_ret, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5 815 `, 816 expAfterPasses: ` 817 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i64, v4:f32, v5:f64) 818 Jump blk_ret, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5, v2, v3, v4, v5 819 `, 820 }, 821 { 822 name: "many_params_many_results", 823 m: testcases.ManyParamsManyResults.Module, 824 targetIndex: 0, 825 exp: ` 826 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i64, v4:f32, v5:f64, v6:i32, v7:i64, v8:f32, v9:f64, v10:i32, v11:i64, v12:f32, v13:f64, v14:i32, v15:i64, v16:f32, v17:f64, v18:i32, v19:i64, v20:f32, v21:f64, v22:i32, v23:i64, v24:f32, v25:f64, v26:i32, v27:i64, v28:f32, v29:f64, v30:i32, v31:i64, v32:f32, v33:f64, v34:i32, v35:i64, v36:f32, v37:f64, v38:i32, v39:i64, v40:f32, v41:f64) 827 Jump blk_ret, v41, v40, v39, v38, v37, v36, v35, v34, v33, v32, v31, v30, v29, v28, v27, v26, v25, v24, v23, v22, v21, v20, v19, v18, v17, v16, v15, v14, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2 828 `, 829 expAfterPasses: ` 830 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i64, v4:f32, v5:f64, v6:i32, v7:i64, v8:f32, v9:f64, v10:i32, v11:i64, v12:f32, v13:f64, v14:i32, v15:i64, v16:f32, v17:f64, v18:i32, v19:i64, v20:f32, v21:f64, v22:i32, v23:i64, v24:f32, v25:f64, v26:i32, v27:i64, v28:f32, v29:f64, v30:i32, v31:i64, v32:f32, v33:f64, v34:i32, v35:i64, v36:f32, v37:f64, v38:i32, v39:i64, v40:f32, v41:f64) 831 Jump blk_ret, v41, v40, v39, v38, v37, v36, v35, v34, v33, v32, v31, v30, v29, v28, v27, v26, v25, v24, v23, v22, v21, v20, v19, v18, v17, v16, v15, v14, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2 832 `, 833 }, 834 { 835 name: "many_middle_values", 836 m: testcases.ManyMiddleValues.Module, 837 exp: ` 838 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:f32) 839 v4:i32 = Iconst_32 0x1 840 v5:i32 = Imul v2, v4 841 v6:i32 = Iconst_32 0x2 842 v7:i32 = Imul v2, v6 843 v8:i32 = Iconst_32 0x3 844 v9:i32 = Imul v2, v8 845 v10:i32 = Iconst_32 0x4 846 v11:i32 = Imul v2, v10 847 v12:i32 = Iconst_32 0x5 848 v13:i32 = Imul v2, v12 849 v14:i32 = Iconst_32 0x6 850 v15:i32 = Imul v2, v14 851 v16:i32 = Iconst_32 0x7 852 v17:i32 = Imul v2, v16 853 v18:i32 = Iconst_32 0x8 854 v19:i32 = Imul v2, v18 855 v20:i32 = Iconst_32 0x9 856 v21:i32 = Imul v2, v20 857 v22:i32 = Iconst_32 0xa 858 v23:i32 = Imul v2, v22 859 v24:i32 = Iconst_32 0xb 860 v25:i32 = Imul v2, v24 861 v26:i32 = Iconst_32 0xc 862 v27:i32 = Imul v2, v26 863 v28:i32 = Iconst_32 0xd 864 v29:i32 = Imul v2, v28 865 v30:i32 = Iconst_32 0xe 866 v31:i32 = Imul v2, v30 867 v32:i32 = Iconst_32 0xf 868 v33:i32 = Imul v2, v32 869 v34:i32 = Iconst_32 0x10 870 v35:i32 = Imul v2, v34 871 v36:i32 = Iconst_32 0x11 872 v37:i32 = Imul v2, v36 873 v38:i32 = Iconst_32 0x12 874 v39:i32 = Imul v2, v38 875 v40:i32 = Iconst_32 0x13 876 v41:i32 = Imul v2, v40 877 v42:i32 = Iconst_32 0x14 878 v43:i32 = Imul v2, v42 879 v44:i32 = Iadd v41, v43 880 v45:i32 = Iadd v39, v44 881 v46:i32 = Iadd v37, v45 882 v47:i32 = Iadd v35, v46 883 v48:i32 = Iadd v33, v47 884 v49:i32 = Iadd v31, v48 885 v50:i32 = Iadd v29, v49 886 v51:i32 = Iadd v27, v50 887 v52:i32 = Iadd v25, v51 888 v53:i32 = Iadd v23, v52 889 v54:i32 = Iadd v21, v53 890 v55:i32 = Iadd v19, v54 891 v56:i32 = Iadd v17, v55 892 v57:i32 = Iadd v15, v56 893 v58:i32 = Iadd v13, v57 894 v59:i32 = Iadd v11, v58 895 v60:i32 = Iadd v9, v59 896 v61:i32 = Iadd v7, v60 897 v62:i32 = Iadd v5, v61 898 v63:f32 = F32const 1.000000 899 v64:f32 = Fmul v3, v63 900 v65:f32 = F32const 2.000000 901 v66:f32 = Fmul v3, v65 902 v67:f32 = F32const 3.000000 903 v68:f32 = Fmul v3, v67 904 v69:f32 = F32const 4.000000 905 v70:f32 = Fmul v3, v69 906 v71:f32 = F32const 5.000000 907 v72:f32 = Fmul v3, v71 908 v73:f32 = F32const 6.000000 909 v74:f32 = Fmul v3, v73 910 v75:f32 = F32const 7.000000 911 v76:f32 = Fmul v3, v75 912 v77:f32 = F32const 8.000000 913 v78:f32 = Fmul v3, v77 914 v79:f32 = F32const 9.000000 915 v80:f32 = Fmul v3, v79 916 v81:f32 = F32const 10.000000 917 v82:f32 = Fmul v3, v81 918 v83:f32 = F32const 11.000000 919 v84:f32 = Fmul v3, v83 920 v85:f32 = F32const 12.000000 921 v86:f32 = Fmul v3, v85 922 v87:f32 = F32const 13.000000 923 v88:f32 = Fmul v3, v87 924 v89:f32 = F32const 14.000000 925 v90:f32 = Fmul v3, v89 926 v91:f32 = F32const 15.000000 927 v92:f32 = Fmul v3, v91 928 v93:f32 = F32const 16.000000 929 v94:f32 = Fmul v3, v93 930 v95:f32 = F32const 17.000000 931 v96:f32 = Fmul v3, v95 932 v97:f32 = F32const 18.000000 933 v98:f32 = Fmul v3, v97 934 v99:f32 = F32const 19.000000 935 v100:f32 = Fmul v3, v99 936 v101:f32 = F32const 20.000000 937 v102:f32 = Fmul v3, v101 938 v103:f32 = Fadd v100, v102 939 v104:f32 = Fadd v98, v103 940 v105:f32 = Fadd v96, v104 941 v106:f32 = Fadd v94, v105 942 v107:f32 = Fadd v92, v106 943 v108:f32 = Fadd v90, v107 944 v109:f32 = Fadd v88, v108 945 v110:f32 = Fadd v86, v109 946 v111:f32 = Fadd v84, v110 947 v112:f32 = Fadd v82, v111 948 v113:f32 = Fadd v80, v112 949 v114:f32 = Fadd v78, v113 950 v115:f32 = Fadd v76, v114 951 v116:f32 = Fadd v74, v115 952 v117:f32 = Fadd v72, v116 953 v118:f32 = Fadd v70, v117 954 v119:f32 = Fadd v68, v118 955 v120:f32 = Fadd v66, v119 956 v121:f32 = Fadd v64, v120 957 Jump blk_ret, v62, v121 958 `, 959 }, 960 { 961 name: "recursive_fibonacci", m: testcases.FibonacciRecursive.Module, 962 exp: ` 963 signatures: 964 sig0: i64i64i32_i32 965 966 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 967 v3:i32 = Iconst_32 0x2 968 v4:i32 = Icmp lt_s, v2, v3 969 Brz v4, blk2 970 Jump blk1 971 972 blk1: () <-- (blk0) 973 Return v2 974 975 blk2: () <-- (blk0) 976 Jump blk3 977 978 blk3: () <-- (blk2) 979 v5:i32 = Iconst_32 0x1 980 v6:i32 = Isub v2, v5 981 v7:i32 = Call f0:sig0, exec_ctx, module_ctx, v6 982 v8:i32 = Iconst_32 0x2 983 v9:i32 = Isub v2, v8 984 v10:i32 = Call f0:sig0, exec_ctx, module_ctx, v9 985 v11:i32 = Iadd v7, v10 986 Jump blk_ret, v11 987 `, 988 expAfterPasses: ` 989 signatures: 990 sig0: i64i64i32_i32 991 992 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 993 v3:i32 = Iconst_32 0x2 994 v4:i32 = Icmp lt_s, v2, v3 995 Brz v4, blk2 996 Jump fallthrough 997 998 blk1: () <-- (blk0) 999 Return v2 1000 1001 blk2: () <-- (blk0) 1002 Jump fallthrough 1003 1004 blk3: () <-- (blk2) 1005 v5:i32 = Iconst_32 0x1 1006 v6:i32 = Isub v2, v5 1007 v7:i32 = Call f0:sig0, exec_ctx, module_ctx, v6 1008 v8:i32 = Iconst_32 0x2 1009 v9:i32 = Isub v2, v8 1010 v10:i32 = Call f0:sig0, exec_ctx, module_ctx, v9 1011 v11:i32 = Iadd v7, v10 1012 Jump blk_ret, v11 1013 `, 1014 }, 1015 { 1016 name: "memory_store_basic", m: testcases.MemoryStoreBasic.Module, 1017 exp: ` 1018 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 1019 v4:i64 = Iconst_64 0x4 1020 v5:i64 = UExtend v2, 32->64 1021 v6:i64 = Uload32 module_ctx, 0x10 1022 v7:i64 = Iadd v5, v4 1023 v8:i32 = Icmp lt_u, v6, v7 1024 ExitIfTrue v8, exec_ctx, memory_out_of_bounds 1025 v9:i64 = Load module_ctx, 0x8 1026 v10:i64 = Iadd v9, v5 1027 Store v3, v10, 0x0 1028 v11:i32 = Load v10, 0x0 1029 Jump blk_ret, v11 1030 `, 1031 }, 1032 { 1033 name: "memory_load_basic", m: testcases.MemoryLoadBasic.Module, 1034 exp: ` 1035 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 1036 v3:i64 = Iconst_64 0x4 1037 v4:i64 = UExtend v2, 32->64 1038 v5:i64 = Uload32 module_ctx, 0x10 1039 v6:i64 = Iadd v4, v3 1040 v7:i32 = Icmp lt_u, v5, v6 1041 ExitIfTrue v7, exec_ctx, memory_out_of_bounds 1042 v8:i64 = Load module_ctx, 0x8 1043 v9:i64 = Iadd v8, v4 1044 v10:i32 = Load v9, 0x0 1045 Jump blk_ret, v10 1046 `, 1047 }, 1048 { 1049 name: "memory_load_basic2", m: testcases.MemoryLoadBasic2.Module, 1050 exp: ` 1051 signatures: 1052 sig1: i64i64_v 1053 1054 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 1055 v3:i32 = Iconst_32 0x0 1056 v4:i32 = Icmp eq, v2, v3 1057 Brz v4, blk2 1058 Jump blk1 1059 1060 blk1: () <-- (blk0) 1061 Call f1:sig1, exec_ctx, module_ctx 1062 v5:i64 = Load module_ctx, 0x8 1063 v6:i64 = Uload32 module_ctx, 0x10 1064 Jump blk3 1065 1066 blk2: () <-- (blk0) 1067 Jump blk3 1068 1069 blk3: () <-- (blk1,blk2) 1070 v7:i64 = Iconst_64 0x4 1071 v8:i64 = UExtend v2, 32->64 1072 v9:i64 = Uload32 module_ctx, 0x10 1073 v10:i64 = Iadd v8, v7 1074 v11:i32 = Icmp lt_u, v9, v10 1075 ExitIfTrue v11, exec_ctx, memory_out_of_bounds 1076 v12:i64 = Load module_ctx, 0x8 1077 v13:i64 = Iadd v12, v8 1078 v14:i32 = Load v13, 0x0 1079 Jump blk_ret, v14 1080 `, 1081 expAfterPasses: ` 1082 signatures: 1083 sig1: i64i64_v 1084 1085 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 1086 v3:i32 = Iconst_32 0x0 1087 v4:i32 = Icmp eq, v2, v3 1088 Brz v4, blk2 1089 Jump fallthrough 1090 1091 blk1: () <-- (blk0) 1092 Call f1:sig1, exec_ctx, module_ctx 1093 Jump blk3 1094 1095 blk2: () <-- (blk0) 1096 Jump fallthrough 1097 1098 blk3: () <-- (blk1,blk2) 1099 v7:i64 = Iconst_64 0x4 1100 v8:i64 = UExtend v2, 32->64 1101 v9:i64 = Uload32 module_ctx, 0x10 1102 v10:i64 = Iadd v8, v7 1103 v11:i32 = Icmp lt_u, v9, v10 1104 ExitIfTrue v11, exec_ctx, memory_out_of_bounds 1105 v12:i64 = Load module_ctx, 0x8 1106 v13:i64 = Iadd v12, v8 1107 v14:i32 = Load v13, 0x0 1108 Jump blk_ret, v14 1109 `, 1110 }, 1111 { 1112 name: "imported_function_call", m: testcases.ImportedFunctionCall.Module, 1113 exp: ` 1114 signatures: 1115 sig1: i64i64i32i32_i32 1116 1117 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 1118 Store module_ctx, exec_ctx, 0x8 1119 v3:i64 = Load module_ctx, 0x8 1120 v4:i64 = Load module_ctx, 0x10 1121 v5:i32 = CallIndirect v3:sig1, exec_ctx, v4, v2, v2 1122 Jump blk_ret, v5 1123 `, 1124 }, 1125 { 1126 name: "memory_loads", m: testcases.MemoryLoads.Module, 1127 exp: ` 1128 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 1129 v3:i64 = Iconst_64 0x4 1130 v4:i64 = UExtend v2, 32->64 1131 v5:i64 = Uload32 module_ctx, 0x10 1132 v6:i64 = Iadd v4, v3 1133 v7:i32 = Icmp lt_u, v5, v6 1134 ExitIfTrue v7, exec_ctx, memory_out_of_bounds 1135 v8:i64 = Load module_ctx, 0x8 1136 v9:i64 = Iadd v8, v4 1137 v10:i32 = Load v9, 0x0 1138 v11:i64 = Iconst_64 0x8 1139 v12:i64 = UExtend v2, 32->64 1140 v13:i64 = Iadd v12, v11 1141 v14:i32 = Icmp lt_u, v5, v13 1142 ExitIfTrue v14, exec_ctx, memory_out_of_bounds 1143 v15:i64 = Load v9, 0x0 1144 v16:f32 = Load v9, 0x0 1145 v17:f64 = Load v9, 0x0 1146 v18:i64 = Iconst_64 0x13 1147 v19:i64 = UExtend v2, 32->64 1148 v20:i64 = Iadd v19, v18 1149 v21:i32 = Icmp lt_u, v5, v20 1150 ExitIfTrue v21, exec_ctx, memory_out_of_bounds 1151 v22:i32 = Load v9, 0xf 1152 v23:i64 = Iconst_64 0x17 1153 v24:i64 = UExtend v2, 32->64 1154 v25:i64 = Iadd v24, v23 1155 v26:i32 = Icmp lt_u, v5, v25 1156 ExitIfTrue v26, exec_ctx, memory_out_of_bounds 1157 v27:i64 = Load v9, 0xf 1158 v28:f32 = Load v9, 0xf 1159 v29:f64 = Load v9, 0xf 1160 v30:i32 = Sload8 v9, 0x0 1161 v31:i32 = Sload8 v9, 0xf 1162 v32:i32 = Uload8 v9, 0x0 1163 v33:i32 = Uload8 v9, 0xf 1164 v34:i32 = Sload16 v9, 0x0 1165 v35:i32 = Sload16 v9, 0xf 1166 v36:i32 = Uload16 v9, 0x0 1167 v37:i32 = Uload16 v9, 0xf 1168 v38:i64 = Sload8 v9, 0x0 1169 v39:i64 = Sload8 v9, 0xf 1170 v40:i64 = Uload8 v9, 0x0 1171 v41:i64 = Uload8 v9, 0xf 1172 v42:i64 = Sload16 v9, 0x0 1173 v43:i64 = Sload16 v9, 0xf 1174 v44:i64 = Uload16 v9, 0x0 1175 v45:i64 = Uload16 v9, 0xf 1176 v46:i64 = Sload32 v9, 0x0 1177 v47:i64 = Sload32 v9, 0xf 1178 v48:i64 = Uload32 v9, 0x0 1179 v49:i64 = Uload32 v9, 0xf 1180 Jump blk_ret, v10, v15, v16, v17, v22, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49 1181 `, 1182 }, 1183 { 1184 name: "globals_get", 1185 m: testcases.GlobalsGet.Module, 1186 exp: ` 1187 blk0: (exec_ctx:i64, module_ctx:i64) 1188 v2:i32 = Load module_ctx, 0x10 1189 v3:i64 = Load module_ctx, 0x20 1190 v4:f32 = Load module_ctx, 0x30 1191 v5:f64 = Load module_ctx, 0x40 1192 v6:v128 = Load module_ctx, 0x50 1193 Jump blk_ret, v2, v3, v4, v5, v6 1194 `, 1195 }, 1196 { 1197 name: "globals_set", 1198 m: testcases.GlobalsSet.Module, 1199 exp: ` 1200 blk0: (exec_ctx:i64, module_ctx:i64) 1201 v2:i32 = Iconst_32 0x1 1202 Store v2, module_ctx, 0x10 1203 v3:i64 = Iconst_64 0x2 1204 Store v3, module_ctx, 0x20 1205 v4:f32 = F32const 3.000000 1206 Store v4, module_ctx, 0x30 1207 v5:f64 = F64const 4.000000 1208 Store v5, module_ctx, 0x40 1209 v6:v128 = Vconst 000000000000000a 0000000000000014 1210 Store v6, module_ctx, 0x50 1211 Jump blk_ret, v2, v3, v4, v5, v6 1212 `, 1213 }, 1214 { 1215 name: "globals_mutable", 1216 m: testcases.GlobalsMutable.Module, 1217 exp: ` 1218 signatures: 1219 sig1: i64i64_v 1220 1221 blk0: (exec_ctx:i64, module_ctx:i64) 1222 v2:i32 = Load module_ctx, 0x10 1223 v3:i64 = Load module_ctx, 0x20 1224 v4:f32 = Load module_ctx, 0x30 1225 v5:f64 = Load module_ctx, 0x40 1226 Call f1:sig1, exec_ctx, module_ctx 1227 v6:i32 = Load module_ctx, 0x10 1228 v7:i64 = Load module_ctx, 0x20 1229 v8:f32 = Load module_ctx, 0x30 1230 v9:f64 = Load module_ctx, 0x40 1231 Jump blk_ret, v2, v3, v4, v5, v6, v7, v8, v9 1232 `, 1233 expAfterPasses: ` 1234 signatures: 1235 sig1: i64i64_v 1236 1237 blk0: (exec_ctx:i64, module_ctx:i64) 1238 v2:i32 = Load module_ctx, 0x10 1239 v3:i64 = Load module_ctx, 0x20 1240 v4:f32 = Load module_ctx, 0x30 1241 v5:f64 = Load module_ctx, 0x40 1242 Call f1:sig1, exec_ctx, module_ctx 1243 v6:i32 = Load module_ctx, 0x10 1244 v7:i64 = Load module_ctx, 0x20 1245 v8:f32 = Load module_ctx, 0x30 1246 v9:f64 = Load module_ctx, 0x40 1247 Jump blk_ret, v2, v3, v4, v5, v6, v7, v8, v9 1248 `, 1249 }, 1250 { 1251 name: "imported_memory_grow", 1252 m: testcases.ImportedMemoryGrow.Module, 1253 exp: ` 1254 signatures: 1255 sig0: i64i64_i32 1256 sig2: i64i32_i32 1257 1258 blk0: (exec_ctx:i64, module_ctx:i64) 1259 Store module_ctx, exec_ctx, 0x8 1260 v2:i64 = Load module_ctx, 0x18 1261 v3:i64 = Load module_ctx, 0x20 1262 v4:i32 = CallIndirect v2:sig0, exec_ctx, v3 1263 v5:i64 = Load module_ctx, 0x8 1264 v6:i64 = Load v5, 0x0 1265 v7:i64 = Load module_ctx, 0x8 1266 v8:i64 = Load v7, 0x8 1267 v9:i64 = Load module_ctx, 0x8 1268 v10:i32 = Load v9, 0x8 1269 v11:i32 = Iconst_32 0x10 1270 v12:i32 = Ushr v10, v11 1271 v13:i32 = Iconst_32 0xa 1272 Store module_ctx, exec_ctx, 0x8 1273 v14:i64 = Load exec_ctx, 0x48 1274 v15:i32 = CallIndirect v14:sig2, exec_ctx, v13 1275 v16:i64 = Load module_ctx, 0x8 1276 v17:i64 = Load v16, 0x0 1277 v18:i64 = Load module_ctx, 0x8 1278 v19:i64 = Load v18, 0x8 1279 Store module_ctx, exec_ctx, 0x8 1280 v20:i64 = Load module_ctx, 0x18 1281 v21:i64 = Load module_ctx, 0x20 1282 v22:i32 = CallIndirect v20:sig0, exec_ctx, v21 1283 v23:i64 = Load module_ctx, 0x8 1284 v24:i64 = Load v23, 0x0 1285 v25:i64 = Load module_ctx, 0x8 1286 v26:i64 = Load v25, 0x8 1287 v27:i64 = Load module_ctx, 0x8 1288 v28:i32 = Load v27, 0x8 1289 v29:i32 = Iconst_32 0x10 1290 v30:i32 = Ushr v28, v29 1291 Jump blk_ret, v4, v12, v22, v30 1292 `, 1293 expAfterPasses: ` 1294 signatures: 1295 sig0: i64i64_i32 1296 sig2: i64i32_i32 1297 1298 blk0: (exec_ctx:i64, module_ctx:i64) 1299 Store module_ctx, exec_ctx, 0x8 1300 v2:i64 = Load module_ctx, 0x18 1301 v3:i64 = Load module_ctx, 0x20 1302 v4:i32 = CallIndirect v2:sig0, exec_ctx, v3 1303 v9:i64 = Load module_ctx, 0x8 1304 v10:i32 = Load v9, 0x8 1305 v11:i32 = Iconst_32 0x10 1306 v12:i32 = Ushr v10, v11 1307 v13:i32 = Iconst_32 0xa 1308 Store module_ctx, exec_ctx, 0x8 1309 v14:i64 = Load exec_ctx, 0x48 1310 v15:i32 = CallIndirect v14:sig2, exec_ctx, v13 1311 Store module_ctx, exec_ctx, 0x8 1312 v20:i64 = Load module_ctx, 0x18 1313 v21:i64 = Load module_ctx, 0x20 1314 v22:i32 = CallIndirect v20:sig0, exec_ctx, v21 1315 v27:i64 = Load module_ctx, 0x8 1316 v28:i32 = Load v27, 0x8 1317 v29:i32 = Iconst_32 0x10 1318 v30:i32 = Ushr v28, v29 1319 Jump blk_ret, v4, v12, v22, v30 1320 `, 1321 }, 1322 { 1323 name: "memory_size_grow", 1324 m: testcases.MemorySizeGrow.Module, 1325 exp: ` 1326 signatures: 1327 sig1: i64i32_i32 1328 1329 blk0: (exec_ctx:i64, module_ctx:i64) 1330 v2:i32 = Iconst_32 0x1 1331 Store module_ctx, exec_ctx, 0x8 1332 v3:i64 = Load exec_ctx, 0x48 1333 v4:i32 = CallIndirect v3:sig1, exec_ctx, v2 1334 v5:i64 = Load module_ctx, 0x8 1335 v6:i64 = Uload32 module_ctx, 0x10 1336 v7:i32 = Load module_ctx, 0x10 1337 v8:i32 = Iconst_32 0x10 1338 v9:i32 = Ushr v7, v8 1339 v10:i32 = Iconst_32 0x1 1340 Store module_ctx, exec_ctx, 0x8 1341 v11:i64 = Load exec_ctx, 0x48 1342 v12:i32 = CallIndirect v11:sig1, exec_ctx, v10 1343 v13:i64 = Load module_ctx, 0x8 1344 v14:i64 = Uload32 module_ctx, 0x10 1345 Jump blk_ret, v4, v9, v12 1346 `, 1347 expAfterPasses: ` 1348 signatures: 1349 sig1: i64i32_i32 1350 1351 blk0: (exec_ctx:i64, module_ctx:i64) 1352 v2:i32 = Iconst_32 0x1 1353 Store module_ctx, exec_ctx, 0x8 1354 v3:i64 = Load exec_ctx, 0x48 1355 v4:i32 = CallIndirect v3:sig1, exec_ctx, v2 1356 v7:i32 = Load module_ctx, 0x10 1357 v8:i32 = Iconst_32 0x10 1358 v9:i32 = Ushr v7, v8 1359 v10:i32 = Iconst_32 0x1 1360 Store module_ctx, exec_ctx, 0x8 1361 v11:i64 = Load exec_ctx, 0x48 1362 v12:i32 = CallIndirect v11:sig1, exec_ctx, v10 1363 Jump blk_ret, v4, v9, v12 1364 `, 1365 }, 1366 { 1367 name: "call_indirect", m: testcases.CallIndirect.Module, 1368 exp: ` 1369 signatures: 1370 sig2: i64i64_i32 1371 1372 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 1373 v3:i64 = Load module_ctx, 0x10 1374 v4:i32 = Load v3, 0x8 1375 v5:i32 = Icmp ge_u, v2, v4 1376 ExitIfTrue v5, exec_ctx, table_out_of_bounds 1377 v6:i64 = Load v3, 0x0 1378 v7:i64 = Iconst_64 0x3 1379 v8:i32 = Ishl v2, v7 1380 v9:i64 = Iadd v6, v8 1381 v10:i64 = Load v9, 0x0 1382 v11:i64 = Iconst_64 0x0 1383 v12:i32 = Icmp eq, v10, v11 1384 ExitIfTrue v12, exec_ctx, indirect_call_null_pointer 1385 v13:i32 = Load v10, 0x10 1386 v14:i64 = Load module_ctx, 0x8 1387 v15:i32 = Load v14, 0x8 1388 v16:i32 = Icmp neq, v13, v15 1389 ExitIfTrue v16, exec_ctx, indirect_call_type_mismatch 1390 v17:i64 = Load v10, 0x0 1391 v18:i64 = Load v10, 0x8 1392 Store module_ctx, exec_ctx, 0x8 1393 v19:i32 = CallIndirect v17:sig2, exec_ctx, v18 1394 Jump blk_ret, v19 1395 `, 1396 }, 1397 { 1398 name: "br_table", m: testcases.BrTable.Module, 1399 exp: ` 1400 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 1401 BrTable v2, [blk7, blk8, blk9, blk10, blk11, blk12, blk13] 1402 1403 blk1: () <-- (blk12) 1404 v8:i32 = Iconst_32 0x10 1405 Return v8 1406 1407 blk2: () <-- (blk11) 1408 v7:i32 = Iconst_32 0xf 1409 Return v7 1410 1411 blk3: () <-- (blk10) 1412 v6:i32 = Iconst_32 0xe 1413 Return v6 1414 1415 blk4: () <-- (blk9) 1416 v5:i32 = Iconst_32 0xd 1417 Return v5 1418 1419 blk5: () <-- (blk8) 1420 v4:i32 = Iconst_32 0xc 1421 Return v4 1422 1423 blk6: () <-- (blk7,blk13) 1424 v3:i32 = Iconst_32 0xb 1425 Return v3 1426 1427 blk7: () <-- (blk0) 1428 Jump blk6 1429 1430 blk8: () <-- (blk0) 1431 Jump blk5 1432 1433 blk9: () <-- (blk0) 1434 Jump blk4 1435 1436 blk10: () <-- (blk0) 1437 Jump blk3 1438 1439 blk11: () <-- (blk0) 1440 Jump blk2 1441 1442 blk12: () <-- (blk0) 1443 Jump blk1 1444 1445 blk13: () <-- (blk0) 1446 Jump blk6 1447 `, 1448 }, 1449 { 1450 name: "br_table_with_arg", m: testcases.BrTableWithArg.Module, 1451 exp: ` 1452 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 1453 BrTable v2, [blk7, blk8, blk9, blk10, blk11, blk12, blk13] 1454 1455 blk1: (v4:i32) <-- (blk12) 1456 v20:i32 = Iconst_32 0x10 1457 v21:i32 = Iadd v4, v20 1458 Return v21 1459 1460 blk2: (v5:i32) <-- (blk11) 1461 v18:i32 = Iconst_32 0xf 1462 v19:i32 = Iadd v5, v18 1463 Return v19 1464 1465 blk3: (v6:i32) <-- (blk10) 1466 v16:i32 = Iconst_32 0xe 1467 v17:i32 = Iadd v6, v16 1468 Return v17 1469 1470 blk4: (v7:i32) <-- (blk9) 1471 v14:i32 = Iconst_32 0xd 1472 v15:i32 = Iadd v7, v14 1473 Return v15 1474 1475 blk5: (v8:i32) <-- (blk8) 1476 v12:i32 = Iconst_32 0xc 1477 v13:i32 = Iadd v8, v12 1478 Return v13 1479 1480 blk6: (v9:i32) <-- (blk7,blk13) 1481 v10:i32 = Iconst_32 0xb 1482 v11:i32 = Iadd v9, v10 1483 Return v11 1484 1485 blk7: () <-- (blk0) 1486 Jump blk6, v3 1487 1488 blk8: () <-- (blk0) 1489 Jump blk5, v3 1490 1491 blk9: () <-- (blk0) 1492 Jump blk4, v3 1493 1494 blk10: () <-- (blk0) 1495 Jump blk3, v3 1496 1497 blk11: () <-- (blk0) 1498 Jump blk2, v3 1499 1500 blk12: () <-- (blk0) 1501 Jump blk1, v3 1502 1503 blk13: () <-- (blk0) 1504 Jump blk6, v3 1505 `, 1506 1507 expAfterPasses: ` 1508 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 1509 BrTable v2, [blk7, blk8, blk9, blk10, blk11, blk12, blk13] 1510 1511 blk7: () <-- (blk0) 1512 Jump blk6 1513 1514 blk8: () <-- (blk0) 1515 Jump fallthrough 1516 1517 blk5: () <-- (blk8) 1518 v12:i32 = Iconst_32 0xc 1519 v13:i32 = Iadd v3, v12 1520 Return v13 1521 1522 blk9: () <-- (blk0) 1523 Jump fallthrough 1524 1525 blk4: () <-- (blk9) 1526 v14:i32 = Iconst_32 0xd 1527 v15:i32 = Iadd v3, v14 1528 Return v15 1529 1530 blk10: () <-- (blk0) 1531 Jump fallthrough 1532 1533 blk3: () <-- (blk10) 1534 v16:i32 = Iconst_32 0xe 1535 v17:i32 = Iadd v3, v16 1536 Return v17 1537 1538 blk11: () <-- (blk0) 1539 Jump fallthrough 1540 1541 blk2: () <-- (blk11) 1542 v18:i32 = Iconst_32 0xf 1543 v19:i32 = Iadd v3, v18 1544 Return v19 1545 1546 blk12: () <-- (blk0) 1547 Jump fallthrough 1548 1549 blk1: () <-- (blk12) 1550 v20:i32 = Iconst_32 0x10 1551 v21:i32 = Iadd v3, v20 1552 Return v21 1553 1554 blk13: () <-- (blk0) 1555 Jump fallthrough 1556 1557 blk6: () <-- (blk7,blk13) 1558 v10:i32 = Iconst_32 0xb 1559 v11:i32 = Iadd v3, v10 1560 Return v11 1561 `, 1562 }, 1563 { 1564 name: "if_then_end_nesting_unreachable_if_then_else_end", m: testcases.IfThenEndNestingUnreachableIfThenElseEnd.Module, 1565 exp: ` 1566 blk0: (exec_ctx:i64, module_ctx:i64, v2:f64, v3:f64, v4:f64) 1567 v6:i32 = Load module_ctx, 0x10 1568 v7:i32 = Iconst_32 0x10 1569 v8:i32 = Ushr v6, v7 1570 Brz v8, blk3 1571 Jump blk2 1572 1573 blk1: (v5:i64) <-- (blk4) 1574 Jump blk_ret 1575 1576 blk2: () <-- (blk0) 1577 v9:i32 = Load module_ctx, 0x10 1578 v10:i32 = Iconst_32 0x10 1579 v11:i32 = Ushr v9, v10 1580 Jump blk4 1581 1582 blk3: () <-- (blk0) 1583 Jump blk4 1584 1585 blk4: () <-- (blk2,blk3) 1586 v12:i64 = Iconst_64 0x0 1587 Jump blk1, v12 1588 `, 1589 expAfterPasses: ` 1590 blk0: (exec_ctx:i64, module_ctx:i64, v2:f64, v3:f64, v4:f64) 1591 v6:i32 = Load module_ctx, 0x10 1592 v7:i32 = Iconst_32 0x10 1593 v8:i32 = Ushr v6, v7 1594 Brz v8, blk3 1595 Jump fallthrough 1596 1597 blk2: () <-- (blk0) 1598 Jump blk4 1599 1600 blk3: () <-- (blk0) 1601 Jump fallthrough 1602 1603 blk4: () <-- (blk2,blk3) 1604 Jump fallthrough 1605 1606 blk1: () <-- (blk4) 1607 Jump blk_ret 1608 `, 1609 }, 1610 { 1611 name: "VecShuffle", 1612 m: testcases.VecShuffle.Module, 1613 exp: ` 1614 blk0: (exec_ctx:i64, module_ctx:i64, v2:v128, v3:v128) 1615 v4:v128 = Shuffle.[0 1 2 3 4 5 6 7 24 25 26 27 28 29 30 31] v2, v3 1616 Jump blk_ret, v4 1617 `, 1618 }, 1619 { 1620 name: "MemoryWait32", 1621 m: testcases.MemoryWait32.Module, 1622 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 1623 exp: ` 1624 signatures: 1625 sig6: i64i64i32i64_i32 1626 1627 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i64) 1628 Store module_ctx, exec_ctx, 0x8 1629 v5:i64 = Iconst_64 0xc 1630 v6:i64 = UExtend v2, 32->64 1631 v7:i64 = Iconst_64 0x10 1632 v8:i64 = Iadd module_ctx, v7 1633 v9:i64 = AtomicLoad_64, v8 1634 v10:i64 = Iadd v6, v5 1635 v11:i32 = Icmp lt_u, v9, v10 1636 ExitIfTrue v11, exec_ctx, memory_out_of_bounds 1637 v12:i64 = Load module_ctx, 0x8 1638 v13:i64 = Iadd v12, v6 1639 v14:i64 = Iconst_64 0x8 1640 v15:i64 = Iadd v13, v14 1641 v16:i64 = Iconst_64 0x3 1642 v17:i64 = Band v15, v16 1643 v18:i64 = Iconst_64 0x0 1644 v19:i32 = Icmp neq, v17, v18 1645 ExitIfTrue v19, exec_ctx, unaligned_atomic 1646 v20:i64 = Load exec_ctx, 0x488 1647 v21:i32 = CallIndirect v20:sig6, exec_ctx, v4, v3, v15 1648 Jump blk_ret, v21 1649 `, 1650 }, 1651 { 1652 name: "MemoryWait64", 1653 m: testcases.MemoryWait64.Module, 1654 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 1655 exp: ` 1656 signatures: 1657 sig7: i64i64i64i64_i32 1658 1659 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i64, v4:i64) 1660 Store module_ctx, exec_ctx, 0x8 1661 v5:i64 = Iconst_64 0x10 1662 v6:i64 = UExtend v2, 32->64 1663 v7:i64 = Iconst_64 0x10 1664 v8:i64 = Iadd module_ctx, v7 1665 v9:i64 = AtomicLoad_64, v8 1666 v10:i64 = Iadd v6, v5 1667 v11:i32 = Icmp lt_u, v9, v10 1668 ExitIfTrue v11, exec_ctx, memory_out_of_bounds 1669 v12:i64 = Load module_ctx, 0x8 1670 v13:i64 = Iadd v12, v6 1671 v14:i64 = Iconst_64 0x8 1672 v15:i64 = Iadd v13, v14 1673 v16:i64 = Iconst_64 0x7 1674 v17:i64 = Band v15, v16 1675 v18:i64 = Iconst_64 0x0 1676 v19:i32 = Icmp neq, v17, v18 1677 ExitIfTrue v19, exec_ctx, unaligned_atomic 1678 v20:i64 = Load exec_ctx, 0x490 1679 v21:i32 = CallIndirect v20:sig7, exec_ctx, v4, v3, v15 1680 Jump blk_ret, v21 1681 `, 1682 }, 1683 { 1684 name: "MemoryNotify", 1685 m: testcases.MemoryNotify.Module, 1686 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 1687 exp: ` 1688 signatures: 1689 sig8: i64i32i64_i32 1690 1691 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32) 1692 Store module_ctx, exec_ctx, 0x8 1693 v4:i64 = Iconst_64 0xc 1694 v5:i64 = UExtend v2, 32->64 1695 v6:i64 = Iconst_64 0x10 1696 v7:i64 = Iadd module_ctx, v6 1697 v8:i64 = AtomicLoad_64, v7 1698 v9:i64 = Iadd v5, v4 1699 v10:i32 = Icmp lt_u, v8, v9 1700 ExitIfTrue v10, exec_ctx, memory_out_of_bounds 1701 v11:i64 = Load module_ctx, 0x8 1702 v12:i64 = Iadd v11, v5 1703 v13:i64 = Iconst_64 0x8 1704 v14:i64 = Iadd v12, v13 1705 v15:i64 = Iconst_64 0x3 1706 v16:i64 = Band v14, v15 1707 v17:i64 = Iconst_64 0x0 1708 v18:i32 = Icmp neq, v16, v17 1709 ExitIfTrue v18, exec_ctx, unaligned_atomic 1710 v19:i64 = Load exec_ctx, 0x498 1711 v20:i32 = CallIndirect v19:sig8, exec_ctx, v3, v14 1712 Jump blk_ret, v20 1713 `, 1714 }, 1715 { 1716 name: "AtomicRMWAdd", 1717 m: testcases.AtomicRmwAdd.Module, 1718 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 1719 exp: ` 1720 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i32, v5:i64, v6:i64, v7:i64, v8:i64) 1721 v9:i32 = Iconst_32 0x0 1722 v10:i64 = Iconst_64 0x1 1723 v11:i64 = UExtend v9, 32->64 1724 v12:i64 = Iconst_64 0x10 1725 v13:i64 = Iadd module_ctx, v12 1726 v14:i64 = AtomicLoad_64, v13 1727 v15:i64 = Iadd v11, v10 1728 v16:i32 = Icmp lt_u, v14, v15 1729 ExitIfTrue v16, exec_ctx, memory_out_of_bounds 1730 v17:i64 = Load module_ctx, 0x8 1731 v18:i64 = Iadd v17, v11 1732 v19:i32 = AtomicRmw add_8, v18, v2 1733 v20:i32 = Iconst_32 0x8 1734 v21:i64 = Iconst_64 0x2 1735 v22:i64 = UExtend v20, 32->64 1736 v23:i64 = Iconst_64 0x10 1737 v24:i64 = Iadd module_ctx, v23 1738 v25:i64 = AtomicLoad_64, v24 1739 v26:i64 = Iadd v22, v21 1740 v27:i32 = Icmp lt_u, v25, v26 1741 ExitIfTrue v27, exec_ctx, memory_out_of_bounds 1742 v28:i64 = Iadd v17, v22 1743 v29:i64 = Iconst_64 0x1 1744 v30:i64 = Band v28, v29 1745 v31:i64 = Iconst_64 0x0 1746 v32:i32 = Icmp neq, v30, v31 1747 ExitIfTrue v32, exec_ctx, unaligned_atomic 1748 v33:i32 = AtomicRmw add_16, v28, v3 1749 v34:i32 = Iconst_32 0x10 1750 v35:i64 = Iconst_64 0x4 1751 v36:i64 = UExtend v34, 32->64 1752 v37:i64 = Iconst_64 0x10 1753 v38:i64 = Iadd module_ctx, v37 1754 v39:i64 = AtomicLoad_64, v38 1755 v40:i64 = Iadd v36, v35 1756 v41:i32 = Icmp lt_u, v39, v40 1757 ExitIfTrue v41, exec_ctx, memory_out_of_bounds 1758 v42:i64 = Iadd v17, v36 1759 v43:i64 = Iconst_64 0x3 1760 v44:i64 = Band v42, v43 1761 v45:i64 = Iconst_64 0x0 1762 v46:i32 = Icmp neq, v44, v45 1763 ExitIfTrue v46, exec_ctx, unaligned_atomic 1764 v47:i32 = AtomicRmw add_32, v42, v4 1765 v48:i32 = Iconst_32 0x18 1766 v49:i64 = Iconst_64 0x1 1767 v50:i64 = UExtend v48, 32->64 1768 v51:i64 = Iconst_64 0x10 1769 v52:i64 = Iadd module_ctx, v51 1770 v53:i64 = AtomicLoad_64, v52 1771 v54:i64 = Iadd v50, v49 1772 v55:i32 = Icmp lt_u, v53, v54 1773 ExitIfTrue v55, exec_ctx, memory_out_of_bounds 1774 v56:i64 = Iadd v17, v50 1775 v57:i64 = AtomicRmw add_8, v56, v5 1776 v58:i32 = Iconst_32 0x20 1777 v59:i64 = Iconst_64 0x2 1778 v60:i64 = UExtend v58, 32->64 1779 v61:i64 = Iconst_64 0x10 1780 v62:i64 = Iadd module_ctx, v61 1781 v63:i64 = AtomicLoad_64, v62 1782 v64:i64 = Iadd v60, v59 1783 v65:i32 = Icmp lt_u, v63, v64 1784 ExitIfTrue v65, exec_ctx, memory_out_of_bounds 1785 v66:i64 = Iadd v17, v60 1786 v67:i64 = Iconst_64 0x1 1787 v68:i64 = Band v66, v67 1788 v69:i64 = Iconst_64 0x0 1789 v70:i32 = Icmp neq, v68, v69 1790 ExitIfTrue v70, exec_ctx, unaligned_atomic 1791 v71:i64 = AtomicRmw add_16, v66, v6 1792 v72:i32 = Iconst_32 0x28 1793 v73:i64 = Iconst_64 0x4 1794 v74:i64 = UExtend v72, 32->64 1795 v75:i64 = Iconst_64 0x10 1796 v76:i64 = Iadd module_ctx, v75 1797 v77:i64 = AtomicLoad_64, v76 1798 v78:i64 = Iadd v74, v73 1799 v79:i32 = Icmp lt_u, v77, v78 1800 ExitIfTrue v79, exec_ctx, memory_out_of_bounds 1801 v80:i64 = Iadd v17, v74 1802 v81:i64 = Iconst_64 0x3 1803 v82:i64 = Band v80, v81 1804 v83:i64 = Iconst_64 0x0 1805 v84:i32 = Icmp neq, v82, v83 1806 ExitIfTrue v84, exec_ctx, unaligned_atomic 1807 v85:i64 = AtomicRmw add_32, v80, v7 1808 v86:i32 = Iconst_32 0x30 1809 v87:i64 = Iconst_64 0x8 1810 v88:i64 = UExtend v86, 32->64 1811 v89:i64 = Iconst_64 0x10 1812 v90:i64 = Iadd module_ctx, v89 1813 v91:i64 = AtomicLoad_64, v90 1814 v92:i64 = Iadd v88, v87 1815 v93:i32 = Icmp lt_u, v91, v92 1816 ExitIfTrue v93, exec_ctx, memory_out_of_bounds 1817 v94:i64 = Iadd v17, v88 1818 v95:i64 = Iconst_64 0x7 1819 v96:i64 = Band v94, v95 1820 v97:i64 = Iconst_64 0x0 1821 v98:i32 = Icmp neq, v96, v97 1822 ExitIfTrue v98, exec_ctx, unaligned_atomic 1823 v99:i64 = AtomicRmw add_64, v94, v8 1824 Jump blk_ret, v19, v33, v47, v57, v71, v85, v99 1825 `, 1826 }, 1827 { 1828 name: "AtomicRMWSub", 1829 m: testcases.AtomicRmwSub.Module, 1830 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 1831 exp: ` 1832 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i32, v5:i64, v6:i64, v7:i64, v8:i64) 1833 v9:i32 = Iconst_32 0x0 1834 v10:i64 = Iconst_64 0x1 1835 v11:i64 = UExtend v9, 32->64 1836 v12:i64 = Iconst_64 0x10 1837 v13:i64 = Iadd module_ctx, v12 1838 v14:i64 = AtomicLoad_64, v13 1839 v15:i64 = Iadd v11, v10 1840 v16:i32 = Icmp lt_u, v14, v15 1841 ExitIfTrue v16, exec_ctx, memory_out_of_bounds 1842 v17:i64 = Load module_ctx, 0x8 1843 v18:i64 = Iadd v17, v11 1844 v19:i32 = AtomicRmw sub_8, v18, v2 1845 v20:i32 = Iconst_32 0x8 1846 v21:i64 = Iconst_64 0x2 1847 v22:i64 = UExtend v20, 32->64 1848 v23:i64 = Iconst_64 0x10 1849 v24:i64 = Iadd module_ctx, v23 1850 v25:i64 = AtomicLoad_64, v24 1851 v26:i64 = Iadd v22, v21 1852 v27:i32 = Icmp lt_u, v25, v26 1853 ExitIfTrue v27, exec_ctx, memory_out_of_bounds 1854 v28:i64 = Iadd v17, v22 1855 v29:i64 = Iconst_64 0x1 1856 v30:i64 = Band v28, v29 1857 v31:i64 = Iconst_64 0x0 1858 v32:i32 = Icmp neq, v30, v31 1859 ExitIfTrue v32, exec_ctx, unaligned_atomic 1860 v33:i32 = AtomicRmw sub_16, v28, v3 1861 v34:i32 = Iconst_32 0x10 1862 v35:i64 = Iconst_64 0x4 1863 v36:i64 = UExtend v34, 32->64 1864 v37:i64 = Iconst_64 0x10 1865 v38:i64 = Iadd module_ctx, v37 1866 v39:i64 = AtomicLoad_64, v38 1867 v40:i64 = Iadd v36, v35 1868 v41:i32 = Icmp lt_u, v39, v40 1869 ExitIfTrue v41, exec_ctx, memory_out_of_bounds 1870 v42:i64 = Iadd v17, v36 1871 v43:i64 = Iconst_64 0x3 1872 v44:i64 = Band v42, v43 1873 v45:i64 = Iconst_64 0x0 1874 v46:i32 = Icmp neq, v44, v45 1875 ExitIfTrue v46, exec_ctx, unaligned_atomic 1876 v47:i32 = AtomicRmw sub_32, v42, v4 1877 v48:i32 = Iconst_32 0x18 1878 v49:i64 = Iconst_64 0x1 1879 v50:i64 = UExtend v48, 32->64 1880 v51:i64 = Iconst_64 0x10 1881 v52:i64 = Iadd module_ctx, v51 1882 v53:i64 = AtomicLoad_64, v52 1883 v54:i64 = Iadd v50, v49 1884 v55:i32 = Icmp lt_u, v53, v54 1885 ExitIfTrue v55, exec_ctx, memory_out_of_bounds 1886 v56:i64 = Iadd v17, v50 1887 v57:i64 = AtomicRmw sub_8, v56, v5 1888 v58:i32 = Iconst_32 0x20 1889 v59:i64 = Iconst_64 0x2 1890 v60:i64 = UExtend v58, 32->64 1891 v61:i64 = Iconst_64 0x10 1892 v62:i64 = Iadd module_ctx, v61 1893 v63:i64 = AtomicLoad_64, v62 1894 v64:i64 = Iadd v60, v59 1895 v65:i32 = Icmp lt_u, v63, v64 1896 ExitIfTrue v65, exec_ctx, memory_out_of_bounds 1897 v66:i64 = Iadd v17, v60 1898 v67:i64 = Iconst_64 0x1 1899 v68:i64 = Band v66, v67 1900 v69:i64 = Iconst_64 0x0 1901 v70:i32 = Icmp neq, v68, v69 1902 ExitIfTrue v70, exec_ctx, unaligned_atomic 1903 v71:i64 = AtomicRmw sub_16, v66, v6 1904 v72:i32 = Iconst_32 0x28 1905 v73:i64 = Iconst_64 0x4 1906 v74:i64 = UExtend v72, 32->64 1907 v75:i64 = Iconst_64 0x10 1908 v76:i64 = Iadd module_ctx, v75 1909 v77:i64 = AtomicLoad_64, v76 1910 v78:i64 = Iadd v74, v73 1911 v79:i32 = Icmp lt_u, v77, v78 1912 ExitIfTrue v79, exec_ctx, memory_out_of_bounds 1913 v80:i64 = Iadd v17, v74 1914 v81:i64 = Iconst_64 0x3 1915 v82:i64 = Band v80, v81 1916 v83:i64 = Iconst_64 0x0 1917 v84:i32 = Icmp neq, v82, v83 1918 ExitIfTrue v84, exec_ctx, unaligned_atomic 1919 v85:i64 = AtomicRmw sub_32, v80, v7 1920 v86:i32 = Iconst_32 0x30 1921 v87:i64 = Iconst_64 0x8 1922 v88:i64 = UExtend v86, 32->64 1923 v89:i64 = Iconst_64 0x10 1924 v90:i64 = Iadd module_ctx, v89 1925 v91:i64 = AtomicLoad_64, v90 1926 v92:i64 = Iadd v88, v87 1927 v93:i32 = Icmp lt_u, v91, v92 1928 ExitIfTrue v93, exec_ctx, memory_out_of_bounds 1929 v94:i64 = Iadd v17, v88 1930 v95:i64 = Iconst_64 0x7 1931 v96:i64 = Band v94, v95 1932 v97:i64 = Iconst_64 0x0 1933 v98:i32 = Icmp neq, v96, v97 1934 ExitIfTrue v98, exec_ctx, unaligned_atomic 1935 v99:i64 = AtomicRmw sub_64, v94, v8 1936 Jump blk_ret, v19, v33, v47, v57, v71, v85, v99 1937 `, 1938 }, 1939 { 1940 name: "AtomicRMWAnd", 1941 m: testcases.AtomicRmwAnd.Module, 1942 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 1943 exp: ` 1944 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i32, v5:i64, v6:i64, v7:i64, v8:i64) 1945 v9:i32 = Iconst_32 0x0 1946 v10:i64 = Iconst_64 0x1 1947 v11:i64 = UExtend v9, 32->64 1948 v12:i64 = Iconst_64 0x10 1949 v13:i64 = Iadd module_ctx, v12 1950 v14:i64 = AtomicLoad_64, v13 1951 v15:i64 = Iadd v11, v10 1952 v16:i32 = Icmp lt_u, v14, v15 1953 ExitIfTrue v16, exec_ctx, memory_out_of_bounds 1954 v17:i64 = Load module_ctx, 0x8 1955 v18:i64 = Iadd v17, v11 1956 v19:i32 = AtomicRmw and_8, v18, v2 1957 v20:i32 = Iconst_32 0x0 1958 v21:i64 = Iconst_64 0xa 1959 v22:i64 = UExtend v20, 32->64 1960 v23:i64 = Iconst_64 0x10 1961 v24:i64 = Iadd module_ctx, v23 1962 v25:i64 = AtomicLoad_64, v24 1963 v26:i64 = Iadd v22, v21 1964 v27:i32 = Icmp lt_u, v25, v26 1965 ExitIfTrue v27, exec_ctx, memory_out_of_bounds 1966 v28:i64 = Iadd v17, v22 1967 v29:i64 = Iconst_64 0x8 1968 v30:i64 = Iadd v28, v29 1969 v31:i64 = Iconst_64 0x1 1970 v32:i64 = Band v30, v31 1971 v33:i64 = Iconst_64 0x0 1972 v34:i32 = Icmp neq, v32, v33 1973 ExitIfTrue v34, exec_ctx, unaligned_atomic 1974 v35:i32 = AtomicRmw and_16, v30, v3 1975 v36:i32 = Iconst_32 0x0 1976 v37:i64 = Iconst_64 0x14 1977 v38:i64 = UExtend v36, 32->64 1978 v39:i64 = Iconst_64 0x10 1979 v40:i64 = Iadd module_ctx, v39 1980 v41:i64 = AtomicLoad_64, v40 1981 v42:i64 = Iadd v38, v37 1982 v43:i32 = Icmp lt_u, v41, v42 1983 ExitIfTrue v43, exec_ctx, memory_out_of_bounds 1984 v44:i64 = Iadd v17, v38 1985 v45:i64 = Iconst_64 0x10 1986 v46:i64 = Iadd v44, v45 1987 v47:i64 = Iconst_64 0x3 1988 v48:i64 = Band v46, v47 1989 v49:i64 = Iconst_64 0x0 1990 v50:i32 = Icmp neq, v48, v49 1991 ExitIfTrue v50, exec_ctx, unaligned_atomic 1992 v51:i32 = AtomicRmw and_32, v46, v4 1993 v52:i32 = Iconst_32 0x0 1994 v53:i64 = Iconst_64 0x19 1995 v54:i64 = UExtend v52, 32->64 1996 v55:i64 = Iconst_64 0x10 1997 v56:i64 = Iadd module_ctx, v55 1998 v57:i64 = AtomicLoad_64, v56 1999 v58:i64 = Iadd v54, v53 2000 v59:i32 = Icmp lt_u, v57, v58 2001 ExitIfTrue v59, exec_ctx, memory_out_of_bounds 2002 v60:i64 = Iadd v17, v54 2003 v61:i64 = Iconst_64 0x18 2004 v62:i64 = Iadd v60, v61 2005 v63:i64 = AtomicRmw and_8, v62, v5 2006 v64:i32 = Iconst_32 0x0 2007 v65:i64 = Iconst_64 0x22 2008 v66:i64 = UExtend v64, 32->64 2009 v67:i64 = Iconst_64 0x10 2010 v68:i64 = Iadd module_ctx, v67 2011 v69:i64 = AtomicLoad_64, v68 2012 v70:i64 = Iadd v66, v65 2013 v71:i32 = Icmp lt_u, v69, v70 2014 ExitIfTrue v71, exec_ctx, memory_out_of_bounds 2015 v72:i64 = Iadd v17, v66 2016 v73:i64 = Iconst_64 0x20 2017 v74:i64 = Iadd v72, v73 2018 v75:i64 = Iconst_64 0x1 2019 v76:i64 = Band v74, v75 2020 v77:i64 = Iconst_64 0x0 2021 v78:i32 = Icmp neq, v76, v77 2022 ExitIfTrue v78, exec_ctx, unaligned_atomic 2023 v79:i64 = AtomicRmw and_16, v74, v6 2024 v80:i32 = Iconst_32 0x0 2025 v81:i64 = Iconst_64 0x2c 2026 v82:i64 = UExtend v80, 32->64 2027 v83:i64 = Iconst_64 0x10 2028 v84:i64 = Iadd module_ctx, v83 2029 v85:i64 = AtomicLoad_64, v84 2030 v86:i64 = Iadd v82, v81 2031 v87:i32 = Icmp lt_u, v85, v86 2032 ExitIfTrue v87, exec_ctx, memory_out_of_bounds 2033 v88:i64 = Iadd v17, v82 2034 v89:i64 = Iconst_64 0x28 2035 v90:i64 = Iadd v88, v89 2036 v91:i64 = Iconst_64 0x3 2037 v92:i64 = Band v90, v91 2038 v93:i64 = Iconst_64 0x0 2039 v94:i32 = Icmp neq, v92, v93 2040 ExitIfTrue v94, exec_ctx, unaligned_atomic 2041 v95:i64 = AtomicRmw and_32, v90, v7 2042 v96:i32 = Iconst_32 0x0 2043 v97:i64 = Iconst_64 0x38 2044 v98:i64 = UExtend v96, 32->64 2045 v99:i64 = Iconst_64 0x10 2046 v100:i64 = Iadd module_ctx, v99 2047 v101:i64 = AtomicLoad_64, v100 2048 v102:i64 = Iadd v98, v97 2049 v103:i32 = Icmp lt_u, v101, v102 2050 ExitIfTrue v103, exec_ctx, memory_out_of_bounds 2051 v104:i64 = Iadd v17, v98 2052 v105:i64 = Iconst_64 0x30 2053 v106:i64 = Iadd v104, v105 2054 v107:i64 = Iconst_64 0x7 2055 v108:i64 = Band v106, v107 2056 v109:i64 = Iconst_64 0x0 2057 v110:i32 = Icmp neq, v108, v109 2058 ExitIfTrue v110, exec_ctx, unaligned_atomic 2059 v111:i64 = AtomicRmw and_64, v106, v8 2060 Jump blk_ret, v19, v35, v51, v63, v79, v95, v111 2061 `, 2062 }, 2063 { 2064 name: "AtomicRMWOr", 2065 m: testcases.AtomicRmwOr.Module, 2066 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 2067 exp: ` 2068 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i32, v5:i64, v6:i64, v7:i64, v8:i64) 2069 v9:i32 = Iconst_32 0x0 2070 v10:i64 = Iconst_64 0x1 2071 v11:i64 = UExtend v9, 32->64 2072 v12:i64 = Iconst_64 0x10 2073 v13:i64 = Iadd module_ctx, v12 2074 v14:i64 = AtomicLoad_64, v13 2075 v15:i64 = Iadd v11, v10 2076 v16:i32 = Icmp lt_u, v14, v15 2077 ExitIfTrue v16, exec_ctx, memory_out_of_bounds 2078 v17:i64 = Load module_ctx, 0x8 2079 v18:i64 = Iadd v17, v11 2080 v19:i32 = AtomicRmw or_8, v18, v2 2081 v20:i32 = Iconst_32 0x0 2082 v21:i64 = Iconst_64 0xa 2083 v22:i64 = UExtend v20, 32->64 2084 v23:i64 = Iconst_64 0x10 2085 v24:i64 = Iadd module_ctx, v23 2086 v25:i64 = AtomicLoad_64, v24 2087 v26:i64 = Iadd v22, v21 2088 v27:i32 = Icmp lt_u, v25, v26 2089 ExitIfTrue v27, exec_ctx, memory_out_of_bounds 2090 v28:i64 = Iadd v17, v22 2091 v29:i64 = Iconst_64 0x8 2092 v30:i64 = Iadd v28, v29 2093 v31:i64 = Iconst_64 0x1 2094 v32:i64 = Band v30, v31 2095 v33:i64 = Iconst_64 0x0 2096 v34:i32 = Icmp neq, v32, v33 2097 ExitIfTrue v34, exec_ctx, unaligned_atomic 2098 v35:i32 = AtomicRmw or_16, v30, v3 2099 v36:i32 = Iconst_32 0x0 2100 v37:i64 = Iconst_64 0x14 2101 v38:i64 = UExtend v36, 32->64 2102 v39:i64 = Iconst_64 0x10 2103 v40:i64 = Iadd module_ctx, v39 2104 v41:i64 = AtomicLoad_64, v40 2105 v42:i64 = Iadd v38, v37 2106 v43:i32 = Icmp lt_u, v41, v42 2107 ExitIfTrue v43, exec_ctx, memory_out_of_bounds 2108 v44:i64 = Iadd v17, v38 2109 v45:i64 = Iconst_64 0x10 2110 v46:i64 = Iadd v44, v45 2111 v47:i64 = Iconst_64 0x3 2112 v48:i64 = Band v46, v47 2113 v49:i64 = Iconst_64 0x0 2114 v50:i32 = Icmp neq, v48, v49 2115 ExitIfTrue v50, exec_ctx, unaligned_atomic 2116 v51:i32 = AtomicRmw or_32, v46, v4 2117 v52:i32 = Iconst_32 0x0 2118 v53:i64 = Iconst_64 0x19 2119 v54:i64 = UExtend v52, 32->64 2120 v55:i64 = Iconst_64 0x10 2121 v56:i64 = Iadd module_ctx, v55 2122 v57:i64 = AtomicLoad_64, v56 2123 v58:i64 = Iadd v54, v53 2124 v59:i32 = Icmp lt_u, v57, v58 2125 ExitIfTrue v59, exec_ctx, memory_out_of_bounds 2126 v60:i64 = Iadd v17, v54 2127 v61:i64 = Iconst_64 0x18 2128 v62:i64 = Iadd v60, v61 2129 v63:i64 = AtomicRmw or_8, v62, v5 2130 v64:i32 = Iconst_32 0x0 2131 v65:i64 = Iconst_64 0x22 2132 v66:i64 = UExtend v64, 32->64 2133 v67:i64 = Iconst_64 0x10 2134 v68:i64 = Iadd module_ctx, v67 2135 v69:i64 = AtomicLoad_64, v68 2136 v70:i64 = Iadd v66, v65 2137 v71:i32 = Icmp lt_u, v69, v70 2138 ExitIfTrue v71, exec_ctx, memory_out_of_bounds 2139 v72:i64 = Iadd v17, v66 2140 v73:i64 = Iconst_64 0x20 2141 v74:i64 = Iadd v72, v73 2142 v75:i64 = Iconst_64 0x1 2143 v76:i64 = Band v74, v75 2144 v77:i64 = Iconst_64 0x0 2145 v78:i32 = Icmp neq, v76, v77 2146 ExitIfTrue v78, exec_ctx, unaligned_atomic 2147 v79:i64 = AtomicRmw or_16, v74, v6 2148 v80:i32 = Iconst_32 0x0 2149 v81:i64 = Iconst_64 0x2c 2150 v82:i64 = UExtend v80, 32->64 2151 v83:i64 = Iconst_64 0x10 2152 v84:i64 = Iadd module_ctx, v83 2153 v85:i64 = AtomicLoad_64, v84 2154 v86:i64 = Iadd v82, v81 2155 v87:i32 = Icmp lt_u, v85, v86 2156 ExitIfTrue v87, exec_ctx, memory_out_of_bounds 2157 v88:i64 = Iadd v17, v82 2158 v89:i64 = Iconst_64 0x28 2159 v90:i64 = Iadd v88, v89 2160 v91:i64 = Iconst_64 0x3 2161 v92:i64 = Band v90, v91 2162 v93:i64 = Iconst_64 0x0 2163 v94:i32 = Icmp neq, v92, v93 2164 ExitIfTrue v94, exec_ctx, unaligned_atomic 2165 v95:i64 = AtomicRmw or_32, v90, v7 2166 v96:i32 = Iconst_32 0x0 2167 v97:i64 = Iconst_64 0x38 2168 v98:i64 = UExtend v96, 32->64 2169 v99:i64 = Iconst_64 0x10 2170 v100:i64 = Iadd module_ctx, v99 2171 v101:i64 = AtomicLoad_64, v100 2172 v102:i64 = Iadd v98, v97 2173 v103:i32 = Icmp lt_u, v101, v102 2174 ExitIfTrue v103, exec_ctx, memory_out_of_bounds 2175 v104:i64 = Iadd v17, v98 2176 v105:i64 = Iconst_64 0x30 2177 v106:i64 = Iadd v104, v105 2178 v107:i64 = Iconst_64 0x7 2179 v108:i64 = Band v106, v107 2180 v109:i64 = Iconst_64 0x0 2181 v110:i32 = Icmp neq, v108, v109 2182 ExitIfTrue v110, exec_ctx, unaligned_atomic 2183 v111:i64 = AtomicRmw or_64, v106, v8 2184 Jump blk_ret, v19, v35, v51, v63, v79, v95, v111 2185 `, 2186 }, 2187 { 2188 name: "AtomicRMWXor", 2189 m: testcases.AtomicRmwXor.Module, 2190 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 2191 exp: ` 2192 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i32, v5:i64, v6:i64, v7:i64, v8:i64) 2193 v9:i32 = Iconst_32 0x0 2194 v10:i64 = Iconst_64 0x1 2195 v11:i64 = UExtend v9, 32->64 2196 v12:i64 = Iconst_64 0x10 2197 v13:i64 = Iadd module_ctx, v12 2198 v14:i64 = AtomicLoad_64, v13 2199 v15:i64 = Iadd v11, v10 2200 v16:i32 = Icmp lt_u, v14, v15 2201 ExitIfTrue v16, exec_ctx, memory_out_of_bounds 2202 v17:i64 = Load module_ctx, 0x8 2203 v18:i64 = Iadd v17, v11 2204 v19:i32 = AtomicRmw xor_8, v18, v2 2205 v20:i32 = Iconst_32 0x0 2206 v21:i64 = Iconst_64 0xa 2207 v22:i64 = UExtend v20, 32->64 2208 v23:i64 = Iconst_64 0x10 2209 v24:i64 = Iadd module_ctx, v23 2210 v25:i64 = AtomicLoad_64, v24 2211 v26:i64 = Iadd v22, v21 2212 v27:i32 = Icmp lt_u, v25, v26 2213 ExitIfTrue v27, exec_ctx, memory_out_of_bounds 2214 v28:i64 = Iadd v17, v22 2215 v29:i64 = Iconst_64 0x8 2216 v30:i64 = Iadd v28, v29 2217 v31:i64 = Iconst_64 0x1 2218 v32:i64 = Band v30, v31 2219 v33:i64 = Iconst_64 0x0 2220 v34:i32 = Icmp neq, v32, v33 2221 ExitIfTrue v34, exec_ctx, unaligned_atomic 2222 v35:i32 = AtomicRmw xor_16, v30, v3 2223 v36:i32 = Iconst_32 0x0 2224 v37:i64 = Iconst_64 0x14 2225 v38:i64 = UExtend v36, 32->64 2226 v39:i64 = Iconst_64 0x10 2227 v40:i64 = Iadd module_ctx, v39 2228 v41:i64 = AtomicLoad_64, v40 2229 v42:i64 = Iadd v38, v37 2230 v43:i32 = Icmp lt_u, v41, v42 2231 ExitIfTrue v43, exec_ctx, memory_out_of_bounds 2232 v44:i64 = Iadd v17, v38 2233 v45:i64 = Iconst_64 0x10 2234 v46:i64 = Iadd v44, v45 2235 v47:i64 = Iconst_64 0x3 2236 v48:i64 = Band v46, v47 2237 v49:i64 = Iconst_64 0x0 2238 v50:i32 = Icmp neq, v48, v49 2239 ExitIfTrue v50, exec_ctx, unaligned_atomic 2240 v51:i32 = AtomicRmw xor_32, v46, v4 2241 v52:i32 = Iconst_32 0x0 2242 v53:i64 = Iconst_64 0x19 2243 v54:i64 = UExtend v52, 32->64 2244 v55:i64 = Iconst_64 0x10 2245 v56:i64 = Iadd module_ctx, v55 2246 v57:i64 = AtomicLoad_64, v56 2247 v58:i64 = Iadd v54, v53 2248 v59:i32 = Icmp lt_u, v57, v58 2249 ExitIfTrue v59, exec_ctx, memory_out_of_bounds 2250 v60:i64 = Iadd v17, v54 2251 v61:i64 = Iconst_64 0x18 2252 v62:i64 = Iadd v60, v61 2253 v63:i64 = AtomicRmw xor_8, v62, v5 2254 v64:i32 = Iconst_32 0x0 2255 v65:i64 = Iconst_64 0x22 2256 v66:i64 = UExtend v64, 32->64 2257 v67:i64 = Iconst_64 0x10 2258 v68:i64 = Iadd module_ctx, v67 2259 v69:i64 = AtomicLoad_64, v68 2260 v70:i64 = Iadd v66, v65 2261 v71:i32 = Icmp lt_u, v69, v70 2262 ExitIfTrue v71, exec_ctx, memory_out_of_bounds 2263 v72:i64 = Iadd v17, v66 2264 v73:i64 = Iconst_64 0x20 2265 v74:i64 = Iadd v72, v73 2266 v75:i64 = Iconst_64 0x1 2267 v76:i64 = Band v74, v75 2268 v77:i64 = Iconst_64 0x0 2269 v78:i32 = Icmp neq, v76, v77 2270 ExitIfTrue v78, exec_ctx, unaligned_atomic 2271 v79:i64 = AtomicRmw xor_16, v74, v6 2272 v80:i32 = Iconst_32 0x0 2273 v81:i64 = Iconst_64 0x2c 2274 v82:i64 = UExtend v80, 32->64 2275 v83:i64 = Iconst_64 0x10 2276 v84:i64 = Iadd module_ctx, v83 2277 v85:i64 = AtomicLoad_64, v84 2278 v86:i64 = Iadd v82, v81 2279 v87:i32 = Icmp lt_u, v85, v86 2280 ExitIfTrue v87, exec_ctx, memory_out_of_bounds 2281 v88:i64 = Iadd v17, v82 2282 v89:i64 = Iconst_64 0x28 2283 v90:i64 = Iadd v88, v89 2284 v91:i64 = Iconst_64 0x3 2285 v92:i64 = Band v90, v91 2286 v93:i64 = Iconst_64 0x0 2287 v94:i32 = Icmp neq, v92, v93 2288 ExitIfTrue v94, exec_ctx, unaligned_atomic 2289 v95:i64 = AtomicRmw xor_32, v90, v7 2290 v96:i32 = Iconst_32 0x0 2291 v97:i64 = Iconst_64 0x38 2292 v98:i64 = UExtend v96, 32->64 2293 v99:i64 = Iconst_64 0x10 2294 v100:i64 = Iadd module_ctx, v99 2295 v101:i64 = AtomicLoad_64, v100 2296 v102:i64 = Iadd v98, v97 2297 v103:i32 = Icmp lt_u, v101, v102 2298 ExitIfTrue v103, exec_ctx, memory_out_of_bounds 2299 v104:i64 = Iadd v17, v98 2300 v105:i64 = Iconst_64 0x30 2301 v106:i64 = Iadd v104, v105 2302 v107:i64 = Iconst_64 0x7 2303 v108:i64 = Band v106, v107 2304 v109:i64 = Iconst_64 0x0 2305 v110:i32 = Icmp neq, v108, v109 2306 ExitIfTrue v110, exec_ctx, unaligned_atomic 2307 v111:i64 = AtomicRmw xor_64, v106, v8 2308 Jump blk_ret, v19, v35, v51, v63, v79, v95, v111 2309 `, 2310 }, 2311 { 2312 name: "AtomicRMWXchg", 2313 m: testcases.AtomicRmwXchg.Module, 2314 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 2315 exp: ` 2316 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i32, v5:i64, v6:i64, v7:i64, v8:i64) 2317 v9:i32 = Iconst_32 0x0 2318 v10:i64 = Iconst_64 0x1 2319 v11:i64 = UExtend v9, 32->64 2320 v12:i64 = Iconst_64 0x10 2321 v13:i64 = Iadd module_ctx, v12 2322 v14:i64 = AtomicLoad_64, v13 2323 v15:i64 = Iadd v11, v10 2324 v16:i32 = Icmp lt_u, v14, v15 2325 ExitIfTrue v16, exec_ctx, memory_out_of_bounds 2326 v17:i64 = Load module_ctx, 0x8 2327 v18:i64 = Iadd v17, v11 2328 v19:i32 = AtomicRmw xchg_8, v18, v2 2329 v20:i32 = Iconst_32 0x0 2330 v21:i64 = Iconst_64 0xa 2331 v22:i64 = UExtend v20, 32->64 2332 v23:i64 = Iconst_64 0x10 2333 v24:i64 = Iadd module_ctx, v23 2334 v25:i64 = AtomicLoad_64, v24 2335 v26:i64 = Iadd v22, v21 2336 v27:i32 = Icmp lt_u, v25, v26 2337 ExitIfTrue v27, exec_ctx, memory_out_of_bounds 2338 v28:i64 = Iadd v17, v22 2339 v29:i64 = Iconst_64 0x8 2340 v30:i64 = Iadd v28, v29 2341 v31:i64 = Iconst_64 0x1 2342 v32:i64 = Band v30, v31 2343 v33:i64 = Iconst_64 0x0 2344 v34:i32 = Icmp neq, v32, v33 2345 ExitIfTrue v34, exec_ctx, unaligned_atomic 2346 v35:i32 = AtomicRmw xchg_16, v30, v3 2347 v36:i32 = Iconst_32 0x0 2348 v37:i64 = Iconst_64 0x14 2349 v38:i64 = UExtend v36, 32->64 2350 v39:i64 = Iconst_64 0x10 2351 v40:i64 = Iadd module_ctx, v39 2352 v41:i64 = AtomicLoad_64, v40 2353 v42:i64 = Iadd v38, v37 2354 v43:i32 = Icmp lt_u, v41, v42 2355 ExitIfTrue v43, exec_ctx, memory_out_of_bounds 2356 v44:i64 = Iadd v17, v38 2357 v45:i64 = Iconst_64 0x10 2358 v46:i64 = Iadd v44, v45 2359 v47:i64 = Iconst_64 0x3 2360 v48:i64 = Band v46, v47 2361 v49:i64 = Iconst_64 0x0 2362 v50:i32 = Icmp neq, v48, v49 2363 ExitIfTrue v50, exec_ctx, unaligned_atomic 2364 v51:i32 = AtomicRmw xchg_32, v46, v4 2365 v52:i32 = Iconst_32 0x0 2366 v53:i64 = Iconst_64 0x19 2367 v54:i64 = UExtend v52, 32->64 2368 v55:i64 = Iconst_64 0x10 2369 v56:i64 = Iadd module_ctx, v55 2370 v57:i64 = AtomicLoad_64, v56 2371 v58:i64 = Iadd v54, v53 2372 v59:i32 = Icmp lt_u, v57, v58 2373 ExitIfTrue v59, exec_ctx, memory_out_of_bounds 2374 v60:i64 = Iadd v17, v54 2375 v61:i64 = Iconst_64 0x18 2376 v62:i64 = Iadd v60, v61 2377 v63:i64 = AtomicRmw xchg_8, v62, v5 2378 v64:i32 = Iconst_32 0x0 2379 v65:i64 = Iconst_64 0x22 2380 v66:i64 = UExtend v64, 32->64 2381 v67:i64 = Iconst_64 0x10 2382 v68:i64 = Iadd module_ctx, v67 2383 v69:i64 = AtomicLoad_64, v68 2384 v70:i64 = Iadd v66, v65 2385 v71:i32 = Icmp lt_u, v69, v70 2386 ExitIfTrue v71, exec_ctx, memory_out_of_bounds 2387 v72:i64 = Iadd v17, v66 2388 v73:i64 = Iconst_64 0x20 2389 v74:i64 = Iadd v72, v73 2390 v75:i64 = Iconst_64 0x1 2391 v76:i64 = Band v74, v75 2392 v77:i64 = Iconst_64 0x0 2393 v78:i32 = Icmp neq, v76, v77 2394 ExitIfTrue v78, exec_ctx, unaligned_atomic 2395 v79:i64 = AtomicRmw xchg_16, v74, v6 2396 v80:i32 = Iconst_32 0x0 2397 v81:i64 = Iconst_64 0x2c 2398 v82:i64 = UExtend v80, 32->64 2399 v83:i64 = Iconst_64 0x10 2400 v84:i64 = Iadd module_ctx, v83 2401 v85:i64 = AtomicLoad_64, v84 2402 v86:i64 = Iadd v82, v81 2403 v87:i32 = Icmp lt_u, v85, v86 2404 ExitIfTrue v87, exec_ctx, memory_out_of_bounds 2405 v88:i64 = Iadd v17, v82 2406 v89:i64 = Iconst_64 0x28 2407 v90:i64 = Iadd v88, v89 2408 v91:i64 = Iconst_64 0x3 2409 v92:i64 = Band v90, v91 2410 v93:i64 = Iconst_64 0x0 2411 v94:i32 = Icmp neq, v92, v93 2412 ExitIfTrue v94, exec_ctx, unaligned_atomic 2413 v95:i64 = AtomicRmw xchg_32, v90, v7 2414 v96:i32 = Iconst_32 0x0 2415 v97:i64 = Iconst_64 0x38 2416 v98:i64 = UExtend v96, 32->64 2417 v99:i64 = Iconst_64 0x10 2418 v100:i64 = Iadd module_ctx, v99 2419 v101:i64 = AtomicLoad_64, v100 2420 v102:i64 = Iadd v98, v97 2421 v103:i32 = Icmp lt_u, v101, v102 2422 ExitIfTrue v103, exec_ctx, memory_out_of_bounds 2423 v104:i64 = Iadd v17, v98 2424 v105:i64 = Iconst_64 0x30 2425 v106:i64 = Iadd v104, v105 2426 v107:i64 = Iconst_64 0x7 2427 v108:i64 = Band v106, v107 2428 v109:i64 = Iconst_64 0x0 2429 v110:i32 = Icmp neq, v108, v109 2430 ExitIfTrue v110, exec_ctx, unaligned_atomic 2431 v111:i64 = AtomicRmw xchg_64, v106, v8 2432 Jump blk_ret, v19, v35, v51, v63, v79, v95, v111 2433 `, 2434 }, 2435 { 2436 name: "AtomicStoreLoad", 2437 m: testcases.AtomicStoreLoad.Module, 2438 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 2439 exp: ` 2440 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i32, v5:i64, v6:i64, v7:i64, v8:i64) 2441 v9:i32 = Iconst_32 0x0 2442 v10:i64 = Iconst_64 0x1 2443 v11:i64 = UExtend v9, 32->64 2444 v12:i64 = Iconst_64 0x10 2445 v13:i64 = Iadd module_ctx, v12 2446 v14:i64 = AtomicLoad_64, v13 2447 v15:i64 = Iadd v11, v10 2448 v16:i32 = Icmp lt_u, v14, v15 2449 ExitIfTrue v16, exec_ctx, memory_out_of_bounds 2450 v17:i64 = Load module_ctx, 0x8 2451 v18:i64 = Iadd v17, v11 2452 AtomicStore_8, v18, v2 2453 v19:i32 = Iconst_32 0x0 2454 v20:i64 = Iconst_64 0x1 2455 v21:i64 = UExtend v19, 32->64 2456 v22:i64 = Iconst_64 0x10 2457 v23:i64 = Iadd module_ctx, v22 2458 v24:i64 = AtomicLoad_64, v23 2459 v25:i64 = Iadd v21, v20 2460 v26:i32 = Icmp lt_u, v24, v25 2461 ExitIfTrue v26, exec_ctx, memory_out_of_bounds 2462 v27:i64 = Iadd v17, v21 2463 v28:i32 = AtomicLoad_8, v27 2464 v29:i32 = Iconst_32 0x0 2465 v30:i64 = Iconst_64 0xa 2466 v31:i64 = UExtend v29, 32->64 2467 v32:i64 = Iconst_64 0x10 2468 v33:i64 = Iadd module_ctx, v32 2469 v34:i64 = AtomicLoad_64, v33 2470 v35:i64 = Iadd v31, v30 2471 v36:i32 = Icmp lt_u, v34, v35 2472 ExitIfTrue v36, exec_ctx, memory_out_of_bounds 2473 v37:i64 = Iadd v17, v31 2474 v38:i64 = Iconst_64 0x8 2475 v39:i64 = Iadd v37, v38 2476 v40:i64 = Iconst_64 0x1 2477 v41:i64 = Band v39, v40 2478 v42:i64 = Iconst_64 0x0 2479 v43:i32 = Icmp neq, v41, v42 2480 ExitIfTrue v43, exec_ctx, unaligned_atomic 2481 AtomicStore_16, v39, v3 2482 v44:i32 = Iconst_32 0x0 2483 v45:i64 = Iconst_64 0xa 2484 v46:i64 = UExtend v44, 32->64 2485 v47:i64 = Iconst_64 0x10 2486 v48:i64 = Iadd module_ctx, v47 2487 v49:i64 = AtomicLoad_64, v48 2488 v50:i64 = Iadd v46, v45 2489 v51:i32 = Icmp lt_u, v49, v50 2490 ExitIfTrue v51, exec_ctx, memory_out_of_bounds 2491 v52:i64 = Iadd v17, v46 2492 v53:i64 = Iconst_64 0x8 2493 v54:i64 = Iadd v52, v53 2494 v55:i64 = Iconst_64 0x1 2495 v56:i64 = Band v54, v55 2496 v57:i64 = Iconst_64 0x0 2497 v58:i32 = Icmp neq, v56, v57 2498 ExitIfTrue v58, exec_ctx, unaligned_atomic 2499 v59:i32 = AtomicLoad_16, v54 2500 v60:i32 = Iconst_32 0x0 2501 v61:i64 = Iconst_64 0x14 2502 v62:i64 = UExtend v60, 32->64 2503 v63:i64 = Iconst_64 0x10 2504 v64:i64 = Iadd module_ctx, v63 2505 v65:i64 = AtomicLoad_64, v64 2506 v66:i64 = Iadd v62, v61 2507 v67:i32 = Icmp lt_u, v65, v66 2508 ExitIfTrue v67, exec_ctx, memory_out_of_bounds 2509 v68:i64 = Iadd v17, v62 2510 v69:i64 = Iconst_64 0x10 2511 v70:i64 = Iadd v68, v69 2512 v71:i64 = Iconst_64 0x3 2513 v72:i64 = Band v70, v71 2514 v73:i64 = Iconst_64 0x0 2515 v74:i32 = Icmp neq, v72, v73 2516 ExitIfTrue v74, exec_ctx, unaligned_atomic 2517 AtomicStore_32, v70, v4 2518 v75:i32 = Iconst_32 0x0 2519 v76:i64 = Iconst_64 0x14 2520 v77:i64 = UExtend v75, 32->64 2521 v78:i64 = Iconst_64 0x10 2522 v79:i64 = Iadd module_ctx, v78 2523 v80:i64 = AtomicLoad_64, v79 2524 v81:i64 = Iadd v77, v76 2525 v82:i32 = Icmp lt_u, v80, v81 2526 ExitIfTrue v82, exec_ctx, memory_out_of_bounds 2527 v83:i64 = Iadd v17, v77 2528 v84:i64 = Iconst_64 0x10 2529 v85:i64 = Iadd v83, v84 2530 v86:i64 = Iconst_64 0x3 2531 v87:i64 = Band v85, v86 2532 v88:i64 = Iconst_64 0x0 2533 v89:i32 = Icmp neq, v87, v88 2534 ExitIfTrue v89, exec_ctx, unaligned_atomic 2535 v90:i32 = AtomicLoad_32, v85 2536 v91:i32 = Iconst_32 0x0 2537 v92:i64 = Iconst_64 0x19 2538 v93:i64 = UExtend v91, 32->64 2539 v94:i64 = Iconst_64 0x10 2540 v95:i64 = Iadd module_ctx, v94 2541 v96:i64 = AtomicLoad_64, v95 2542 v97:i64 = Iadd v93, v92 2543 v98:i32 = Icmp lt_u, v96, v97 2544 ExitIfTrue v98, exec_ctx, memory_out_of_bounds 2545 v99:i64 = Iadd v17, v93 2546 v100:i64 = Iconst_64 0x18 2547 v101:i64 = Iadd v99, v100 2548 AtomicStore_8, v101, v5 2549 v102:i32 = Iconst_32 0x0 2550 v103:i64 = Iconst_64 0x19 2551 v104:i64 = UExtend v102, 32->64 2552 v105:i64 = Iconst_64 0x10 2553 v106:i64 = Iadd module_ctx, v105 2554 v107:i64 = AtomicLoad_64, v106 2555 v108:i64 = Iadd v104, v103 2556 v109:i32 = Icmp lt_u, v107, v108 2557 ExitIfTrue v109, exec_ctx, memory_out_of_bounds 2558 v110:i64 = Iadd v17, v104 2559 v111:i64 = Iconst_64 0x18 2560 v112:i64 = Iadd v110, v111 2561 v113:i64 = AtomicLoad_8, v112 2562 v114:i32 = Iconst_32 0x0 2563 v115:i64 = Iconst_64 0x22 2564 v116:i64 = UExtend v114, 32->64 2565 v117:i64 = Iconst_64 0x10 2566 v118:i64 = Iadd module_ctx, v117 2567 v119:i64 = AtomicLoad_64, v118 2568 v120:i64 = Iadd v116, v115 2569 v121:i32 = Icmp lt_u, v119, v120 2570 ExitIfTrue v121, exec_ctx, memory_out_of_bounds 2571 v122:i64 = Iadd v17, v116 2572 v123:i64 = Iconst_64 0x20 2573 v124:i64 = Iadd v122, v123 2574 v125:i64 = Iconst_64 0x1 2575 v126:i64 = Band v124, v125 2576 v127:i64 = Iconst_64 0x0 2577 v128:i32 = Icmp neq, v126, v127 2578 ExitIfTrue v128, exec_ctx, unaligned_atomic 2579 AtomicStore_16, v124, v6 2580 v129:i32 = Iconst_32 0x0 2581 v130:i64 = Iconst_64 0x22 2582 v131:i64 = UExtend v129, 32->64 2583 v132:i64 = Iconst_64 0x10 2584 v133:i64 = Iadd module_ctx, v132 2585 v134:i64 = AtomicLoad_64, v133 2586 v135:i64 = Iadd v131, v130 2587 v136:i32 = Icmp lt_u, v134, v135 2588 ExitIfTrue v136, exec_ctx, memory_out_of_bounds 2589 v137:i64 = Iadd v17, v131 2590 v138:i64 = Iconst_64 0x20 2591 v139:i64 = Iadd v137, v138 2592 v140:i64 = Iconst_64 0x1 2593 v141:i64 = Band v139, v140 2594 v142:i64 = Iconst_64 0x0 2595 v143:i32 = Icmp neq, v141, v142 2596 ExitIfTrue v143, exec_ctx, unaligned_atomic 2597 v144:i64 = AtomicLoad_16, v139 2598 v145:i32 = Iconst_32 0x0 2599 v146:i64 = Iconst_64 0x2c 2600 v147:i64 = UExtend v145, 32->64 2601 v148:i64 = Iconst_64 0x10 2602 v149:i64 = Iadd module_ctx, v148 2603 v150:i64 = AtomicLoad_64, v149 2604 v151:i64 = Iadd v147, v146 2605 v152:i32 = Icmp lt_u, v150, v151 2606 ExitIfTrue v152, exec_ctx, memory_out_of_bounds 2607 v153:i64 = Iadd v17, v147 2608 v154:i64 = Iconst_64 0x28 2609 v155:i64 = Iadd v153, v154 2610 v156:i64 = Iconst_64 0x3 2611 v157:i64 = Band v155, v156 2612 v158:i64 = Iconst_64 0x0 2613 v159:i32 = Icmp neq, v157, v158 2614 ExitIfTrue v159, exec_ctx, unaligned_atomic 2615 AtomicStore_32, v155, v7 2616 v160:i32 = Iconst_32 0x0 2617 v161:i64 = Iconst_64 0x2c 2618 v162:i64 = UExtend v160, 32->64 2619 v163:i64 = Iconst_64 0x10 2620 v164:i64 = Iadd module_ctx, v163 2621 v165:i64 = AtomicLoad_64, v164 2622 v166:i64 = Iadd v162, v161 2623 v167:i32 = Icmp lt_u, v165, v166 2624 ExitIfTrue v167, exec_ctx, memory_out_of_bounds 2625 v168:i64 = Iadd v17, v162 2626 v169:i64 = Iconst_64 0x28 2627 v170:i64 = Iadd v168, v169 2628 v171:i64 = Iconst_64 0x3 2629 v172:i64 = Band v170, v171 2630 v173:i64 = Iconst_64 0x0 2631 v174:i32 = Icmp neq, v172, v173 2632 ExitIfTrue v174, exec_ctx, unaligned_atomic 2633 v175:i64 = AtomicLoad_32, v170 2634 v176:i32 = Iconst_32 0x0 2635 v177:i64 = Iconst_64 0x38 2636 v178:i64 = UExtend v176, 32->64 2637 v179:i64 = Iconst_64 0x10 2638 v180:i64 = Iadd module_ctx, v179 2639 v181:i64 = AtomicLoad_64, v180 2640 v182:i64 = Iadd v178, v177 2641 v183:i32 = Icmp lt_u, v181, v182 2642 ExitIfTrue v183, exec_ctx, memory_out_of_bounds 2643 v184:i64 = Iadd v17, v178 2644 v185:i64 = Iconst_64 0x30 2645 v186:i64 = Iadd v184, v185 2646 v187:i64 = Iconst_64 0x7 2647 v188:i64 = Band v186, v187 2648 v189:i64 = Iconst_64 0x0 2649 v190:i32 = Icmp neq, v188, v189 2650 ExitIfTrue v190, exec_ctx, unaligned_atomic 2651 AtomicStore_64, v186, v8 2652 v191:i32 = Iconst_32 0x0 2653 v192:i64 = Iconst_64 0x38 2654 v193:i64 = UExtend v191, 32->64 2655 v194:i64 = Iconst_64 0x10 2656 v195:i64 = Iadd module_ctx, v194 2657 v196:i64 = AtomicLoad_64, v195 2658 v197:i64 = Iadd v193, v192 2659 v198:i32 = Icmp lt_u, v196, v197 2660 ExitIfTrue v198, exec_ctx, memory_out_of_bounds 2661 v199:i64 = Iadd v17, v193 2662 v200:i64 = Iconst_64 0x30 2663 v201:i64 = Iadd v199, v200 2664 v202:i64 = Iconst_64 0x7 2665 v203:i64 = Band v201, v202 2666 v204:i64 = Iconst_64 0x0 2667 v205:i32 = Icmp neq, v203, v204 2668 ExitIfTrue v205, exec_ctx, unaligned_atomic 2669 v206:i64 = AtomicLoad_64, v201 2670 Jump blk_ret, v28, v59, v90, v113, v144, v175, v206 2671 `, 2672 }, 2673 { 2674 name: "AtomicCas", 2675 m: testcases.AtomicCas.Module, 2676 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 2677 exp: ` 2678 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i32, v5:i32, v6:i32, v7:i32, v8:i64, v9:i64, v10:i64, v11:i64, v12:i64, v13:i64, v14:i64, v15:i64) 2679 v16:i32 = Iconst_32 0x0 2680 v17:i64 = Iconst_64 0x1 2681 v18:i64 = UExtend v16, 32->64 2682 v19:i64 = Iconst_64 0x10 2683 v20:i64 = Iadd module_ctx, v19 2684 v21:i64 = AtomicLoad_64, v20 2685 v22:i64 = Iadd v18, v17 2686 v23:i32 = Icmp lt_u, v21, v22 2687 ExitIfTrue v23, exec_ctx, memory_out_of_bounds 2688 v24:i64 = Load module_ctx, 0x8 2689 v25:i64 = Iadd v24, v18 2690 v26:i32 = AtomicCas_8, v25, v2, v3 2691 v27:i32 = Iconst_32 0x0 2692 v28:i64 = Iconst_64 0xa 2693 v29:i64 = UExtend v27, 32->64 2694 v30:i64 = Iconst_64 0x10 2695 v31:i64 = Iadd module_ctx, v30 2696 v32:i64 = AtomicLoad_64, v31 2697 v33:i64 = Iadd v29, v28 2698 v34:i32 = Icmp lt_u, v32, v33 2699 ExitIfTrue v34, exec_ctx, memory_out_of_bounds 2700 v35:i64 = Iadd v24, v29 2701 v36:i64 = Iconst_64 0x8 2702 v37:i64 = Iadd v35, v36 2703 v38:i64 = Iconst_64 0x1 2704 v39:i64 = Band v37, v38 2705 v40:i64 = Iconst_64 0x0 2706 v41:i32 = Icmp neq, v39, v40 2707 ExitIfTrue v41, exec_ctx, unaligned_atomic 2708 v42:i32 = AtomicCas_16, v37, v4, v5 2709 v43:i32 = Iconst_32 0x0 2710 v44:i64 = Iconst_64 0x14 2711 v45:i64 = UExtend v43, 32->64 2712 v46:i64 = Iconst_64 0x10 2713 v47:i64 = Iadd module_ctx, v46 2714 v48:i64 = AtomicLoad_64, v47 2715 v49:i64 = Iadd v45, v44 2716 v50:i32 = Icmp lt_u, v48, v49 2717 ExitIfTrue v50, exec_ctx, memory_out_of_bounds 2718 v51:i64 = Iadd v24, v45 2719 v52:i64 = Iconst_64 0x10 2720 v53:i64 = Iadd v51, v52 2721 v54:i64 = Iconst_64 0x3 2722 v55:i64 = Band v53, v54 2723 v56:i64 = Iconst_64 0x0 2724 v57:i32 = Icmp neq, v55, v56 2725 ExitIfTrue v57, exec_ctx, unaligned_atomic 2726 v58:i32 = AtomicCas_32, v53, v6, v7 2727 v59:i32 = Iconst_32 0x0 2728 v60:i64 = Iconst_64 0x19 2729 v61:i64 = UExtend v59, 32->64 2730 v62:i64 = Iconst_64 0x10 2731 v63:i64 = Iadd module_ctx, v62 2732 v64:i64 = AtomicLoad_64, v63 2733 v65:i64 = Iadd v61, v60 2734 v66:i32 = Icmp lt_u, v64, v65 2735 ExitIfTrue v66, exec_ctx, memory_out_of_bounds 2736 v67:i64 = Iadd v24, v61 2737 v68:i64 = Iconst_64 0x18 2738 v69:i64 = Iadd v67, v68 2739 v70:i64 = AtomicCas_8, v69, v8, v9 2740 v71:i32 = Iconst_32 0x0 2741 v72:i64 = Iconst_64 0x22 2742 v73:i64 = UExtend v71, 32->64 2743 v74:i64 = Iconst_64 0x10 2744 v75:i64 = Iadd module_ctx, v74 2745 v76:i64 = AtomicLoad_64, v75 2746 v77:i64 = Iadd v73, v72 2747 v78:i32 = Icmp lt_u, v76, v77 2748 ExitIfTrue v78, exec_ctx, memory_out_of_bounds 2749 v79:i64 = Iadd v24, v73 2750 v80:i64 = Iconst_64 0x20 2751 v81:i64 = Iadd v79, v80 2752 v82:i64 = Iconst_64 0x1 2753 v83:i64 = Band v81, v82 2754 v84:i64 = Iconst_64 0x0 2755 v85:i32 = Icmp neq, v83, v84 2756 ExitIfTrue v85, exec_ctx, unaligned_atomic 2757 v86:i64 = AtomicCas_16, v81, v10, v11 2758 v87:i32 = Iconst_32 0x0 2759 v88:i64 = Iconst_64 0x2c 2760 v89:i64 = UExtend v87, 32->64 2761 v90:i64 = Iconst_64 0x10 2762 v91:i64 = Iadd module_ctx, v90 2763 v92:i64 = AtomicLoad_64, v91 2764 v93:i64 = Iadd v89, v88 2765 v94:i32 = Icmp lt_u, v92, v93 2766 ExitIfTrue v94, exec_ctx, memory_out_of_bounds 2767 v95:i64 = Iadd v24, v89 2768 v96:i64 = Iconst_64 0x28 2769 v97:i64 = Iadd v95, v96 2770 v98:i64 = Iconst_64 0x3 2771 v99:i64 = Band v97, v98 2772 v100:i64 = Iconst_64 0x0 2773 v101:i32 = Icmp neq, v99, v100 2774 ExitIfTrue v101, exec_ctx, unaligned_atomic 2775 v102:i64 = AtomicCas_32, v97, v12, v13 2776 v103:i32 = Iconst_32 0x0 2777 v104:i64 = Iconst_64 0x38 2778 v105:i64 = UExtend v103, 32->64 2779 v106:i64 = Iconst_64 0x10 2780 v107:i64 = Iadd module_ctx, v106 2781 v108:i64 = AtomicLoad_64, v107 2782 v109:i64 = Iadd v105, v104 2783 v110:i32 = Icmp lt_u, v108, v109 2784 ExitIfTrue v110, exec_ctx, memory_out_of_bounds 2785 v111:i64 = Iadd v24, v105 2786 v112:i64 = Iconst_64 0x30 2787 v113:i64 = Iadd v111, v112 2788 v114:i64 = Iconst_64 0x7 2789 v115:i64 = Band v113, v114 2790 v116:i64 = Iconst_64 0x0 2791 v117:i32 = Icmp neq, v115, v116 2792 ExitIfTrue v117, exec_ctx, unaligned_atomic 2793 v118:i64 = AtomicCas_64, v113, v14, v15 2794 Jump blk_ret, v26, v42, v58, v70, v86, v102, v118 2795 `, 2796 }, 2797 { 2798 name: "AtomicFence", 2799 m: testcases.AtomicFence.Module, 2800 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 2801 exp: ` 2802 blk0: (exec_ctx:i64, module_ctx:i64) 2803 Fence 0 2804 Jump blk_ret 2805 `, 2806 }, 2807 { 2808 name: "AtomicFenceNoMemory", 2809 m: testcases.AtomicFenceNoMemory.Module, 2810 features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, 2811 exp: ` 2812 blk0: (exec_ctx:i64, module_ctx:i64) 2813 Jump blk_ret 2814 `, 2815 }, 2816 { 2817 name: "bounds check in if-else", 2818 m: &wasm.Module{ 2819 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{wasm.ValueTypeI32}}}, 2820 FunctionSection: []wasm.Index{0}, 2821 CodeSection: []wasm.Code{{ 2822 Body: []byte{ 2823 wasm.OpcodeLocalGet, 0, 2824 wasm.OpcodeI32Load, 0x2, 0x20, // alignment=2 (natural alignment) staticOffset=0x20 2825 wasm.OpcodeDrop, 2826 2827 wasm.OpcodeLocalGet, 0, 2828 wasm.OpcodeIf, 0x40, // blockSignature:vv. 2829 /* */ wasm.OpcodeLocalGet, 0, 2830 /* */ // This bound check should be removed since it's known to be in bounds. 2831 /* */ wasm.OpcodeI32Load, 0x2, 0x10, // alignment=2 (natural alignment) staticOffset=0x20 2832 /* */ wasm.OpcodeDrop, 2833 wasm.OpcodeElse, 2834 /* */ wasm.OpcodeLocalGet, 0, 2835 /* */ // This bound check should be removed since it's known to be in bounds. 2836 /* */ wasm.OpcodeI32Load, 0x2, 0x10, // alignment=2 (natural alignment) staticOffset=0x20 2837 /* */ wasm.OpcodeDrop, 2838 /* */ // This shouldn't be removed since it's not known to be in bounds. 2839 /* */ wasm.OpcodeLocalGet, 0, 2840 /* */ wasm.OpcodeI32Load, 0x2, 0x30, // alignment=2 (natural alignment) staticOffset=0x20 2841 /* */ wasm.OpcodeDrop, 2842 /* */ // But this is known to be in bounds. 2843 /* */ wasm.OpcodeLocalGet, 0, 2844 /* */ wasm.OpcodeI32Load, 0x2, 0x25, // alignment=2 (natural alignment) staticOffset=0x20 2845 /* */ wasm.OpcodeDrop, 2846 wasm.OpcodeEnd, 2847 2848 // At this point, the known bound 0x20 should be retained. 2849 wasm.OpcodeLocalGet, 0, 2850 wasm.OpcodeI32Load, 0x2, 0x15, // alignment=2 (natural alignment) staticOffset=0x20 2851 wasm.OpcodeDrop, 2852 2853 wasm.OpcodeEnd, 2854 }, 2855 }}, 2856 MemorySection: &wasm.Memory{Min: 1}, 2857 }, 2858 features: api.CoreFeaturesV2, 2859 exp: ` 2860 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 2861 v3:i64 = Iconst_64 0x24 2862 v4:i64 = UExtend v2, 32->64 2863 v5:i64 = Uload32 module_ctx, 0x10 2864 v6:i64 = Iadd v4, v3 2865 v7:i32 = Icmp lt_u, v5, v6 2866 ExitIfTrue v7, exec_ctx, memory_out_of_bounds 2867 v8:i64 = Load module_ctx, 0x8 2868 v9:i64 = Iadd v8, v4 2869 v10:i32 = Load v9, 0x20 2870 Brz v2, blk2 2871 Jump blk1 2872 2873 blk1: () <-- (blk0) 2874 v11:i32 = Load v9, 0x10 2875 Jump blk3 2876 2877 blk2: () <-- (blk0) 2878 v12:i32 = Load v9, 0x10 2879 v13:i64 = Iconst_64 0x34 2880 v14:i64 = UExtend v2, 32->64 2881 v15:i64 = Iadd v14, v13 2882 v16:i32 = Icmp lt_u, v5, v15 2883 ExitIfTrue v16, exec_ctx, memory_out_of_bounds 2884 v17:i32 = Load v9, 0x30 2885 v18:i32 = Load v9, 0x25 2886 Jump blk3 2887 2888 blk3: () <-- (blk1,blk2) 2889 v19:i64 = Load module_ctx, 0x8 2890 v20:i64 = UExtend v2, 32->64 2891 v21:i64 = Iadd v19, v20 2892 v22:i32 = Load v21, 0x15 2893 Jump blk_ret 2894 `, 2895 }, 2896 { 2897 name: "bounds check in loop with if-else", 2898 m: &wasm.Module{ 2899 TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{wasm.ValueTypeI32}}}, 2900 FunctionSection: []wasm.Index{0}, 2901 CodeSection: []wasm.Code{{ 2902 Body: []byte{ 2903 wasm.OpcodeLocalGet, 0, 2904 wasm.OpcodeI32Load, 0x2, 0x10, // staticOffset=0x20 2905 wasm.OpcodeDrop, 2906 2907 wasm.OpcodeLoop, 0x40, // blockSignature:vv. 2908 2909 /* */ wasm.OpcodeLocalGet, 0, 2910 // This address must be always recomputed: 2911 // v9 in `Load v9, 0x20` won't propagate from blk0 to blk1, 2912 /* */ wasm.OpcodeI32Load, 0x2, 0x20, // staticOffset=0x30 2913 2914 /* */ wasm.OpcodeIf, 0x40, // blockSignature:vv. 2915 /* */ /* */ wasm.OpcodeLoop, 0x40, // blockSignature:vv. 2916 /* */ /* */ /* */ wasm.OpcodeLocalGet, 0, 2917 /* */ /* */ /* */ wasm.OpcodeI32Load, 0x2, 0x50, // staticOffset=0x50 2918 /* */ /* */ /* */ wasm.OpcodeBrIf, 2, // quit to the inner loop 2919 /* */ /* */ wasm.OpcodeEnd, 2920 /* */ wasm.OpcodeElse, 2921 /* */ /* */ wasm.OpcodeLocalGet, 0, 2922 /* */ /* */ wasm.OpcodeBrIf, 2, // quit to the outer loop 2923 /* */ wasm.OpcodeEnd, 2924 /* */ wasm.OpcodeBr, 1, // quit to the loop 2925 2926 wasm.OpcodeEnd, // end loop 2927 2928 wasm.OpcodeEnd, 2929 }, 2930 }}, 2931 MemorySection: &wasm.Memory{Min: 1}, 2932 }, 2933 features: api.CoreFeaturesV2, 2934 exp: ` 2935 blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) 2936 v3:i64 = Iconst_64 0x14 2937 v4:i64 = UExtend v2, 32->64 2938 v5:i64 = Uload32 module_ctx, 0x10 2939 v6:i64 = Iadd v4, v3 2940 v7:i32 = Icmp lt_u, v5, v6 2941 ExitIfTrue v7, exec_ctx, memory_out_of_bounds 2942 v8:i64 = Load module_ctx, 0x8 2943 v9:i64 = Iadd v8, v4 2944 v10:i32 = Load v9, 0x10 2945 Jump blk1 2946 2947 blk1: () <-- (blk0,blk6) 2948 v11:i64 = Iconst_64 0x24 2949 v12:i64 = UExtend v2, 32->64 2950 v13:i64 = Uload32 module_ctx, 0x10 2951 v14:i64 = Iadd v12, v11 2952 v15:i32 = Icmp lt_u, v13, v14 2953 ExitIfTrue v15, exec_ctx, memory_out_of_bounds 2954 v16:i64 = Load module_ctx, 0x8 2955 v17:i64 = Iadd v16, v12 2956 v18:i32 = Load v17, 0x20 2957 Brz v18, blk4 2958 Jump blk3 2959 2960 blk2: () 2961 2962 blk3: () <-- (blk1) 2963 Jump blk6 2964 2965 blk4: () <-- (blk1) 2966 Brnz v2, blk_ret 2967 Jump blk9 2968 2969 blk5: () <-- (blk7,blk9) 2970 Jump blk_ret 2971 2972 blk6: () <-- (blk3) 2973 v19:i64 = Iconst_64 0x54 2974 v20:i64 = UExtend v2, 32->64 2975 v21:i64 = Uload32 module_ctx, 0x10 2976 v22:i64 = Iadd v20, v19 2977 v23:i32 = Icmp lt_u, v21, v22 2978 ExitIfTrue v23, exec_ctx, memory_out_of_bounds 2979 v24:i64 = Load module_ctx, 0x8 2980 v25:i64 = Iadd v24, v20 2981 v26:i32 = Load v25, 0x50 2982 Brnz v26, blk1 2983 Jump blk8 2984 2985 blk7: () <-- (blk8) 2986 Jump blk5 2987 2988 blk8: () <-- (blk6) 2989 Jump blk7 2990 2991 blk9: () <-- (blk4) 2992 Jump blk5 2993 `, 2994 }, 2995 } { 2996 2997 tc := tc 2998 t.Run(tc.name, func(t *testing.T) { 2999 // Just in case let's check the test module is valid. 3000 features := tc.features 3001 if features == 0 { 3002 features = api.CoreFeaturesV2 3003 } 3004 err := tc.m.Validate(features) 3005 require.NoError(t, err, "invalid test case module!") 3006 3007 b := ssa.NewBuilder() 3008 3009 offset := wazevoapi.NewModuleContextOffsetData(tc.m, tc.needListener) 3010 fc := NewFrontendCompiler(tc.m, b, &offset, tc.ensureTermination, tc.needListener, false) 3011 typeIndex := tc.m.FunctionSection[tc.targetIndex] 3012 code := &tc.m.CodeSection[tc.targetIndex] 3013 fc.Init(tc.targetIndex, typeIndex, &tc.m.TypeSection[typeIndex], code.LocalTypes, code.Body, tc.needListener, 0) 3014 3015 fc.LowerToSSA() 3016 3017 actual := fc.formatBuilder() 3018 require.Equal(t, tc.exp, actual) 3019 3020 b.RunPasses() 3021 if expAfterOpt := tc.expAfterPasses; expAfterOpt != "" { 3022 actualAfterOpt := fc.formatBuilder() 3023 require.Equal(t, expAfterOpt, actualAfterOpt) 3024 } 3025 }) 3026 } 3027 } 3028 3029 func TestSignatureForListener(t *testing.T) { 3030 for _, tc := range []struct { 3031 name string 3032 sig *wasm.FunctionType 3033 before, after *ssa.Signature 3034 }{ 3035 { 3036 name: "empty", 3037 sig: &wasm.FunctionType{}, 3038 before: &ssa.Signature{Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32}}, 3039 after: &ssa.Signature{Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32}}, 3040 }, 3041 { 3042 name: "multi", 3043 sig: &wasm.FunctionType{ 3044 Params: []wasm.ValueType{wasm.ValueTypeF64, wasm.ValueTypeI32}, 3045 Results: []wasm.ValueType{ 3046 wasm.ValueTypeI64, wasm.ValueTypeI32, wasm.ValueTypeF32, wasm.ValueTypeF64, wasm.ValueTypeV128, 3047 }, 3048 }, 3049 before: &ssa.Signature{ 3050 Params: []ssa.Type{ 3051 ssa.TypeI64, ssa.TypeI32, 3052 ssa.TypeF64, ssa.TypeI32, 3053 }, 3054 }, 3055 after: &ssa.Signature{ 3056 Params: []ssa.Type{ 3057 ssa.TypeI64, ssa.TypeI32, 3058 ssa.TypeI64, ssa.TypeI32, ssa.TypeF32, ssa.TypeF64, ssa.TypeV128, 3059 }, 3060 }, 3061 }, 3062 } { 3063 tc := tc 3064 t.Run(tc.name, func(t *testing.T) { 3065 before, after := SignatureForListener(tc.sig) 3066 require.Equal(t, tc.before, before) 3067 require.Equal(t, tc.after, after) 3068 }) 3069 } 3070 } 3071 3072 func TestCompiler_declareSignatures(t *testing.T) { 3073 m := &wasm.Module{ 3074 TypeSection: []wasm.FunctionType{ 3075 {}, 3076 {Params: []wasm.ValueType{wasm.ValueTypeI64, wasm.ValueTypeI32}}, 3077 {Params: []wasm.ValueType{wasm.ValueTypeF64, wasm.ValueTypeI32}}, 3078 {Results: []wasm.ValueType{wasm.ValueTypeI64, wasm.ValueTypeI32}}, 3079 }, 3080 } 3081 3082 t.Run("listener=false", func(t *testing.T) { 3083 builder := ssa.NewBuilder() 3084 c := &Compiler{m: m, ssaBuilder: builder} 3085 c.declareSignatures(false) 3086 3087 declaredSigs := builder.Signatures() 3088 expected := []*ssa.Signature{ 3089 {ID: 0, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64}}, 3090 {ID: 1, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI64, ssa.TypeI32}}, 3091 {ID: 2, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeF64, ssa.TypeI32}}, 3092 {ID: 3, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64}, Results: []ssa.Type{ssa.TypeI64, ssa.TypeI32}}, 3093 {ID: 4, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32}, Results: []ssa.Type{ssa.TypeI32}}, 3094 {ID: 5, Params: []ssa.Type{ssa.TypeI64}}, 3095 {ID: 6, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32, ssa.TypeI32, ssa.TypeI64}, Results: []ssa.Type{ssa.TypeI32}}, 3096 {ID: 7, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32}, Results: []ssa.Type{ssa.TypeI64}}, 3097 {ID: 8, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI64}}, 3098 {ID: 9, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64}, Results: []ssa.Type{ssa.TypeI32}}, 3099 {ID: 10, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI64, ssa.TypeI64}, Results: []ssa.Type{ssa.TypeI32}}, 3100 {ID: 11, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32, ssa.TypeI64}, Results: []ssa.Type{ssa.TypeI32}}, 3101 } 3102 3103 require.Equal(t, len(expected), len(declaredSigs)) 3104 for i := 0; i < len(expected); i++ { 3105 require.Equal(t, expected[i].String(), declaredSigs[i].String(), i) 3106 } 3107 }) 3108 3109 t.Run("listener=false", func(t *testing.T) { 3110 builder := ssa.NewBuilder() 3111 c := &Compiler{m: m, ssaBuilder: builder} 3112 c.declareSignatures(true) 3113 3114 declaredSigs := builder.Signatures() 3115 3116 expected := []*ssa.Signature{ 3117 {ID: 0, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64}}, 3118 {ID: 1, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI64, ssa.TypeI32}}, 3119 {ID: 2, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeF64, ssa.TypeI32}}, 3120 {ID: 3, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64}, Results: []ssa.Type{ssa.TypeI64, ssa.TypeI32}}, 3121 // Before. 3122 {ID: 4, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32}}, 3123 {ID: 5, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeI32}}, 3124 {ID: 6, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32, ssa.TypeF64, ssa.TypeI32}}, 3125 {ID: 7, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32}}, 3126 // After. 3127 {ID: 8, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32}}, 3128 {ID: 9, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32}}, 3129 {ID: 10, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32}}, 3130 {ID: 11, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32, ssa.TypeI64, ssa.TypeI32}}, 3131 // Misc. 3132 {ID: 12, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32}, Results: []ssa.Type{ssa.TypeI32}}, 3133 {ID: 13, Params: []ssa.Type{ssa.TypeI64}}, 3134 {ID: 14, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32, ssa.TypeI32, ssa.TypeI64}, Results: []ssa.Type{ssa.TypeI32}}, 3135 {ID: 15, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32}, Results: []ssa.Type{ssa.TypeI64}}, 3136 {ID: 16, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI64}}, 3137 {ID: 17, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI32, ssa.TypeI64}, Results: []ssa.Type{ssa.TypeI32}}, 3138 {ID: 18, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI64, ssa.TypeI64, ssa.TypeI64}, Results: []ssa.Type{ssa.TypeI32}}, 3139 {ID: 19, Params: []ssa.Type{ssa.TypeI64, ssa.TypeI32, ssa.TypeI64}, Results: []ssa.Type{ssa.TypeI32}}, 3140 } 3141 require.Equal(t, len(expected), len(declaredSigs)) 3142 for i := 0; i < len(declaredSigs); i++ { 3143 require.Equal(t, expected[i].String(), declaredSigs[i].String(), i) 3144 } 3145 }) 3146 } 3147 3148 func TestCompiler_recordKnownSafeBound(t *testing.T) { 3149 c := &Compiler{} 3150 c.recordKnownSafeBound(1, 99, 9999) 3151 require.Equal(t, 1, len(c.knownSafeBoundsSet)) 3152 require.True(t, c.getKnownSafeBound(1).valid()) 3153 require.Equal(t, uint64(99), c.getKnownSafeBound(1).bound) 3154 require.Equal(t, ssa.Value(9999), c.getKnownSafeBound(1).absoluteAddr) 3155 3156 c.recordKnownSafeBound(1, 150, 9999) 3157 require.Equal(t, 1, len(c.knownSafeBoundsSet)) 3158 require.Equal(t, uint64(150), c.getKnownSafeBound(1).bound) 3159 3160 c.recordKnownSafeBound(5, 666, 54321) 3161 require.Equal(t, 2, len(c.knownSafeBoundsSet)) 3162 require.Equal(t, uint64(666), c.getKnownSafeBound(5).bound) 3163 require.Equal(t, ssa.Value(54321), c.getKnownSafeBound(5).absoluteAddr) 3164 } 3165 3166 func TestCompiler_getKnownSafeBound(t *testing.T) { 3167 c := &Compiler{ 3168 knownSafeBounds: []knownSafeBound{ 3169 {}, {bound: 2134}, 3170 }, 3171 } 3172 require.Nil(t, c.getKnownSafeBound(5)) 3173 require.Nil(t, c.getKnownSafeBound(12345)) 3174 require.False(t, c.getKnownSafeBound(0).valid()) 3175 require.True(t, c.getKnownSafeBound(1).valid()) 3176 } 3177 3178 func TestCompiler_clearSafeBounds(t *testing.T) { 3179 c := &Compiler{} 3180 c.knownSafeBounds = []knownSafeBound{{bound: 1}, {}, {bound: 2}, {}, {}, {bound: 3}} 3181 c.knownSafeBoundsSet = []ssa.ValueID{0, 2, 5} 3182 c.clearSafeBounds() 3183 require.Equal(t, 0, len(c.knownSafeBoundsSet)) 3184 require.Equal(t, []knownSafeBound{{absoluteAddr: ssa.ValueInvalid}, {}, {absoluteAddr: ssa.ValueInvalid}, {}, {}, {absoluteAddr: ssa.ValueInvalid}}, c.knownSafeBounds) 3185 } 3186 3187 func TestCompiler_resetAbsoluteAddressInSafeBounds(t *testing.T) { 3188 c := &Compiler{} 3189 c.knownSafeBounds = []knownSafeBound{ 3190 {bound: 1, absoluteAddr: ssa.Value(1)}, 3191 {}, 3192 {bound: 2, absoluteAddr: ssa.Value(2)}, 3193 {}, 3194 {}, 3195 {bound: 3, absoluteAddr: ssa.Value(3)}, 3196 } 3197 c.knownSafeBoundsSet = []ssa.ValueID{0, 2, 5} 3198 c.resetAbsoluteAddressInSafeBounds() 3199 require.Equal(t, 3, len(c.knownSafeBoundsSet)) 3200 require.Equal(t, []knownSafeBound{ 3201 {bound: 1, absoluteAddr: ssa.ValueInvalid}, 3202 {}, 3203 {bound: 2, absoluteAddr: ssa.ValueInvalid}, 3204 {}, 3205 {}, 3206 {bound: 3, absoluteAddr: ssa.ValueInvalid}, 3207 }, c.knownSafeBounds) 3208 } 3209 3210 func TestKnownSafeBound_valid(t *testing.T) { 3211 k := &knownSafeBound{bound: 10, absoluteAddr: 12345} 3212 require.True(t, k.valid()) 3213 k.bound = 0 3214 require.False(t, k.valid()) 3215 } 3216 3217 func TestCompiler_finalizeKnownSafeBoundsAtTheEndOoBlock(t *testing.T) { 3218 c := NewFrontendCompiler(&wasm.Module{}, ssa.NewBuilder(), nil, false, false, false) 3219 blk := c.ssaBuilder.AllocateBasicBlock() 3220 require.True(t, len(c.getKnownSafeBoundsAtTheEndOfBlocks(blk.ID()).View()) == 0) 3221 c.ssaBuilder.SetCurrentBlock(blk) 3222 c.knownSafeBoundsSet = []ssa.ValueID{0, 2, 5} 3223 c.knownSafeBounds = []knownSafeBound{ 3224 {bound: 1, absoluteAddr: ssa.Value(1)}, 3225 {}, 3226 {bound: 2, absoluteAddr: ssa.Value(2)}, 3227 {}, 3228 {}, 3229 {bound: 3, absoluteAddr: ssa.Value(3)}, 3230 } 3231 c.finalizeKnownSafeBoundsAtTheEndOfBlock(blk.ID()) 3232 require.True(t, len(c.knownSafeBoundsSet) == 0) 3233 finalized := c.getKnownSafeBoundsAtTheEndOfBlocks(blk.ID()) 3234 require.Equal(t, 3, len(finalized.View())) 3235 } 3236 3237 func TestCompiler_initializeCurrentBlockKnownBounds(t *testing.T) { 3238 t.Run("single (sealed)", func(t *testing.T) { 3239 c := NewFrontendCompiler(&wasm.Module{}, ssa.NewBuilder(), nil, false, false, false) 3240 builder := c.ssaBuilder 3241 child := builder.AllocateBasicBlock() 3242 { 3243 parent := builder.AllocateBasicBlock() 3244 builder.SetCurrentBlock(parent) 3245 c.recordKnownSafeBound(1, 99, 9999) 3246 c.recordKnownSafeBound(2, 150, 9999) 3247 c.recordKnownSafeBound(5, 666, 54321) 3248 builder.AllocateInstruction().AsJump(ssa.ValuesNil, child).Insert(builder) 3249 c.finalizeKnownSafeBoundsAtTheEndOfBlock(parent.ID()) 3250 } 3251 3252 // Seal the child: the absolute addresses will be propagated. 3253 builder.Seal(child) 3254 builder.SetCurrentBlock(child) 3255 c.initializeCurrentBlockKnownBounds() 3256 kb := c.getKnownSafeBound(1) 3257 require.True(t, kb.valid()) 3258 require.Equal(t, uint64(99), kb.bound) 3259 require.Equal(t, ssa.Value(9999), kb.absoluteAddr) 3260 kb = c.getKnownSafeBound(2) 3261 require.True(t, kb.valid()) 3262 require.Equal(t, uint64(150), kb.bound) 3263 require.Equal(t, ssa.Value(9999), kb.absoluteAddr) 3264 kb = c.getKnownSafeBound(5) 3265 require.True(t, kb.valid()) 3266 require.Equal(t, uint64(666), kb.bound) 3267 require.Equal(t, ssa.Value(54321), kb.absoluteAddr) 3268 }) 3269 t.Run("single (unsealed)", func(t *testing.T) { 3270 c := NewFrontendCompiler(&wasm.Module{}, ssa.NewBuilder(), nil, false, false, false) 3271 builder := c.ssaBuilder 3272 child := builder.AllocateBasicBlock() 3273 { 3274 parent := builder.AllocateBasicBlock() 3275 builder.SetCurrentBlock(parent) 3276 c.recordKnownSafeBound(1, 99, 9999) 3277 c.recordKnownSafeBound(2, 150, 9999) 3278 c.recordKnownSafeBound(5, 666, 54321) 3279 builder.AllocateInstruction().AsJump(ssa.ValuesNil, child).Insert(builder) 3280 c.finalizeKnownSafeBoundsAtTheEndOfBlock(parent.ID()) 3281 } 3282 3283 // Do not seal the child: the absolute addresses will be recomputed. 3284 builder.SetCurrentBlock(child) 3285 c.initializeCurrentBlockKnownBounds() 3286 kb := c.getKnownSafeBound(1) 3287 require.True(t, kb.valid()) 3288 require.Equal(t, uint64(99), kb.bound) 3289 require.NotEqual(t, ssa.Value(9999), kb.absoluteAddr) 3290 kb = c.getKnownSafeBound(2) 3291 require.True(t, kb.valid()) 3292 require.Equal(t, uint64(150), kb.bound) 3293 require.NotEqual(t, ssa.Value(9999), kb.absoluteAddr) 3294 kb = c.getKnownSafeBound(5) 3295 require.True(t, kb.valid()) 3296 require.Equal(t, uint64(666), kb.bound) 3297 require.NotEqual(t, ssa.Value(54321), kb.absoluteAddr) 3298 }) 3299 t.Run("multiple predecessors", func(t *testing.T) { 3300 c := NewFrontendCompiler(&wasm.Module{}, ssa.NewBuilder(), nil, false, false, false) 3301 builder := c.ssaBuilder 3302 child := builder.AllocateBasicBlock() 3303 { 3304 p1 := builder.AllocateBasicBlock() 3305 builder.SetCurrentBlock(p1) 3306 c.recordKnownSafeBound(1, 99, 9999) 3307 c.recordKnownSafeBound(2, 150, 9999) 3308 c.recordKnownSafeBound(5, 666, 54321) 3309 c.recordKnownSafeBound(592131, 666, 54321) 3310 builder.AllocateInstruction().AsJump(ssa.ValuesNil, child).Insert(builder) 3311 c.finalizeKnownSafeBoundsAtTheEndOfBlock(p1.ID()) 3312 } 3313 { 3314 p2 := builder.AllocateBasicBlock() 3315 builder.SetCurrentBlock(p2) 3316 c.recordKnownSafeBound(1, 100, 999419) 3317 c.recordKnownSafeBound(2, 4, 9991239) 3318 c.recordKnownSafeBound(5, 555, 54341221) 3319 c.recordKnownSafeBound(6, 666, 54321) 3320 c.recordKnownSafeBound(7, 666, 54321) 3321 builder.AllocateInstruction().AsJump(ssa.ValuesNil, child).Insert(builder) 3322 c.finalizeKnownSafeBoundsAtTheEndOfBlock(p2.ID()) 3323 } 3324 { 3325 p3 := builder.AllocateBasicBlock() 3326 builder.SetCurrentBlock(p3) 3327 c.recordKnownSafeBound(1, 1, 999419) 3328 c.recordKnownSafeBound(2, 11111, 9991239) 3329 c.recordKnownSafeBound(5, 5551231, 54341221) 3330 c.recordKnownSafeBound(7, 666, 54321) 3331 c.recordKnownSafeBound(60, 666, 54321) 3332 builder.AllocateInstruction().AsJump(ssa.ValuesNil, child).Insert(builder) 3333 c.finalizeKnownSafeBoundsAtTheEndOfBlock(p3.ID()) 3334 } 3335 3336 builder.SetCurrentBlock(child) 3337 c.initializeCurrentBlockKnownBounds() 3338 for _, tc := range []struct { 3339 id ssa.ValueID 3340 valid bool 3341 bound uint64 3342 }{ 3343 {id: 0, valid: false}, 3344 {id: 1, valid: true, bound: 1}, 3345 {id: 2, valid: true, bound: 4}, 3346 {id: 3, valid: false}, 3347 {id: 4, valid: false}, 3348 {id: 5, valid: true, bound: 555}, 3349 {id: 6, valid: false}, 3350 {id: 7, valid: false}, 3351 {id: 60, valid: false}, 3352 {id: 592131, valid: false}, 3353 } { 3354 t.Run(fmt.Sprintf("id=%d", tc.id), func(t *testing.T) { 3355 kb := c.getKnownSafeBound(tc.id) 3356 require.Equal(t, tc.valid, kb.valid()) 3357 if kb.valid() { 3358 require.Equal(t, tc.bound, kb.bound) 3359 require.Equal(t, ssa.ValueInvalid, kb.absoluteAddr) 3360 } 3361 }) 3362 } 3363 }) 3364 }