github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/integration_test/spectest/v2/testdata/int_exprs.wast (about)

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