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  }