github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/integration_test/spectest/v1/testdata/float_exprs.wast (about)

     1  ;; Test interesting floating-point "expressions". These tests contain code
     2  ;; patterns which tempt common value-changing optimizations.
     3  
     4  ;; Test that x*y+z is not done with x87-style intermediate precision.
     5  
     6  (module
     7    (func (export "f64.no_contraction") (param $x f64) (param $y f64) (param $z f64) (result f64)
     8      (f64.add (f64.mul (local.get $x) (local.get $y)) (local.get $z)))
     9  )
    10  
    11  (assert_return (invoke "f64.no_contraction" (f64.const -0x1.9e87ce14273afp-103) (f64.const 0x1.2515ad31db63ep+664) (f64.const 0x1.868c6685e6185p+533)) (f64.const -0x1.da94885b11493p+561))
    12  (assert_return (invoke "f64.no_contraction" (f64.const 0x1.da21c460a6f44p+52) (f64.const 0x1.60859d2e7714ap-321) (f64.const 0x1.e63f1b7b660e1p-302)) (f64.const 0x1.4672f256d1794p-268))
    13  (assert_return (invoke "f64.no_contraction" (f64.const -0x1.f3eaf43f327cp-594) (f64.const 0x1.dfcc009906b57p+533) (f64.const 0x1.5984e03c520a1p-104)) (f64.const -0x1.d4797fb3db166p-60))
    14  (assert_return (invoke "f64.no_contraction" (f64.const 0x1.dab6c772cb2e2p-69) (f64.const -0x1.d761663679a84p-101) (f64.const 0x1.f22f92c843226p-218)) (f64.const -0x1.b50d72dfcef68p-169))
    15  (assert_return (invoke "f64.no_contraction" (f64.const -0x1.87c5def1e4d3dp-950) (f64.const -0x1.50cd5dab2207fp+935) (f64.const 0x1.e629bd0da8c5dp-54)) (f64.const 0x1.01b6feb4e78a7p-14))
    16  
    17  ;; Test that x*y+z is not folded to fma.
    18  
    19  (module
    20    (func (export "f32.no_fma") (param $x f32) (param $y f32) (param $z f32) (result f32)
    21      (f32.add (f32.mul (local.get $x) (local.get $y)) (local.get $z)))
    22    (func (export "f64.no_fma") (param $x f64) (param $y f64) (param $z f64) (result f64)
    23      (f64.add (f64.mul (local.get $x) (local.get $y)) (local.get $z)))
    24  )
    25  
    26  (assert_return (invoke "f32.no_fma" (f32.const 0x1.a78402p+124) (f32.const 0x1.cf8548p-23) (f32.const 0x1.992adap+107)) (f32.const 0x1.a5262cp+107))
    27  (assert_return (invoke "f32.no_fma" (f32.const 0x1.ed15a4p-28) (f32.const -0x1.613c72p-50) (f32.const 0x1.4757bp-88)) (f32.const -0x1.5406b8p-77))
    28  (assert_return (invoke "f32.no_fma" (f32.const 0x1.ae63a2p+37) (f32.const 0x1.b3a59ap-13) (f32.const 0x1.c16918p+10)) (f32.const 0x1.6e385cp+25))
    29  (assert_return (invoke "f32.no_fma" (f32.const 0x1.2a77fap-8) (f32.const -0x1.bb7356p+22) (f32.const -0x1.32be2ap+1)) (f32.const -0x1.0286d4p+15))
    30  (assert_return (invoke "f32.no_fma" (f32.const 0x1.298fb6p+126) (f32.const -0x1.03080cp-70) (f32.const -0x1.418de6p+34)) (f32.const -0x1.2d15c6p+56))
    31  (assert_return (invoke "f64.no_fma" (f64.const 0x1.ac357ff46eed4p+557) (f64.const 0x1.852c01a5e7297p+430) (f64.const -0x1.05995704eda8ap+987)) (f64.const 0x1.855d905d338ep+987))
    32  (assert_return (invoke "f64.no_fma" (f64.const 0x1.e2fd6bf32010cp+749) (f64.const 0x1.01c2238d405e4p-130) (f64.const 0x1.2ecc0db4b9f94p+573)) (f64.const 0x1.e64eb07e063bcp+619))
    33  (assert_return (invoke "f64.no_fma" (f64.const 0x1.92b7c7439ede3p-721) (f64.const -0x1.6aa97586d3de6p+1011) (f64.const 0x1.8de4823f6358ap+237)) (f64.const -0x1.1d4139fd20ecdp+291))
    34  (assert_return (invoke "f64.no_fma" (f64.const -0x1.466d30bddb453p-386) (f64.const -0x1.185a4d739c7aap+443) (f64.const 0x1.5f9c436fbfc7bp+55)) (f64.const 0x1.bd61a350fcc1ap+57))
    35  (assert_return (invoke "f64.no_fma" (f64.const 0x1.7e2c44058a799p+52) (f64.const 0x1.c73b71765b8b2p+685) (f64.const -0x1.16c641df0b108p+690)) (f64.const 0x1.53ccb53de0bd1p+738))
    36  
    37  ;; Test that x+0.0 is not folded to x.
    38  ;; See IEEE 754-2008 10.4 "Literal meaning and value-changing optimizations".
    39  
    40  (module
    41    (func (export "f32.no_fold_add_zero") (param $x f32) (result f32)
    42      (f32.add (local.get $x) (f32.const 0.0)))
    43    (func (export "f64.no_fold_add_zero") (param $x f64) (result f64)
    44      (f64.add (local.get $x) (f64.const 0.0)))
    45  )
    46  
    47  (assert_return (invoke "f32.no_fold_add_zero" (f32.const -0.0)) (f32.const 0.0))
    48  (assert_return (invoke "f64.no_fold_add_zero" (f64.const -0.0)) (f64.const 0.0))
    49  (assert_return (invoke "f32.no_fold_add_zero" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
    50  (assert_return (invoke "f64.no_fold_add_zero" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
    51  
    52  ;; Test that 0.0 - x is not folded to -x.
    53  
    54  (module
    55    (func (export "f32.no_fold_zero_sub") (param $x f32) (result f32)
    56      (f32.sub (f32.const 0.0) (local.get $x)))
    57    (func (export "f64.no_fold_zero_sub") (param $x f64) (result f64)
    58      (f64.sub (f64.const 0.0) (local.get $x)))
    59  )
    60  
    61  (assert_return (invoke "f32.no_fold_zero_sub" (f32.const 0.0)) (f32.const 0.0))
    62  (assert_return (invoke "f64.no_fold_zero_sub" (f64.const 0.0)) (f64.const 0.0))
    63  (assert_return (invoke "f32.no_fold_zero_sub" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
    64  (assert_return (invoke "f64.no_fold_zero_sub" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
    65  
    66  ;; Test that x - 0.0 is not folded to x.
    67  
    68  (module
    69    (func (export "f32.no_fold_sub_zero") (param $x f32) (result f32)
    70      (f32.sub (local.get $x) (f32.const 0.0)))
    71    (func (export "f64.no_fold_sub_zero") (param $x f64) (result f64)
    72      (f64.sub (local.get $x) (f64.const 0.0)))
    73  )
    74  
    75  (assert_return (invoke "f32.no_fold_sub_zero" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
    76  (assert_return (invoke "f64.no_fold_sub_zero" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
    77  
    78  ;; Test that x*0.0 is not folded to 0.0.
    79  
    80  (module
    81    (func (export "f32.no_fold_mul_zero") (param $x f32) (result f32)
    82      (f32.mul (local.get $x) (f32.const 0.0)))
    83    (func (export "f64.no_fold_mul_zero") (param $x f64) (result f64)
    84      (f64.mul (local.get $x) (f64.const 0.0)))
    85  )
    86  
    87  (assert_return (invoke "f32.no_fold_mul_zero" (f32.const -0.0)) (f32.const -0.0))
    88  (assert_return (invoke "f32.no_fold_mul_zero" (f32.const -1.0)) (f32.const -0.0))
    89  (assert_return (invoke "f32.no_fold_mul_zero" (f32.const -2.0)) (f32.const -0.0))
    90  (assert_return (invoke "f32.no_fold_mul_zero" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
    91  (assert_return (invoke "f64.no_fold_mul_zero" (f64.const -0.0)) (f64.const -0.0))
    92  (assert_return (invoke "f64.no_fold_mul_zero" (f64.const -1.0)) (f64.const -0.0))
    93  (assert_return (invoke "f64.no_fold_mul_zero" (f64.const -2.0)) (f64.const -0.0))
    94  (assert_return (invoke "f64.no_fold_mul_zero" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
    95  
    96  ;; Test that x*1.0 is not folded to x.
    97  ;; See IEEE 754-2008 10.4 "Literal meaning and value-changing optimizations".
    98  
    99  (module
   100    (func (export "f32.no_fold_mul_one") (param $x f32) (result f32)
   101      (f32.mul (local.get $x) (f32.const 1.0)))
   102    (func (export "f64.no_fold_mul_one") (param $x f64) (result f64)
   103      (f64.mul (local.get $x) (f64.const 1.0)))
   104  )
   105  
   106  (assert_return (invoke "f32.no_fold_mul_one" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
   107  (assert_return (invoke "f64.no_fold_mul_one" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
   108  
   109  ;; Test that 0.0/x is not folded to 0.0.
   110  
   111  (module
   112    (func (export "f32.no_fold_zero_div") (param $x f32) (result f32)
   113      (f32.div (f32.const 0.0) (local.get $x)))
   114    (func (export "f64.no_fold_zero_div") (param $x f64) (result f64)
   115      (f64.div (f64.const 0.0) (local.get $x)))
   116  )
   117  
   118  (assert_return (invoke "f32.no_fold_zero_div" (f32.const 0.0)) (f32.const nan:canonical))
   119  (assert_return (invoke "f32.no_fold_zero_div" (f32.const -0.0)) (f32.const nan:canonical))
   120  (assert_return (invoke "f32.no_fold_zero_div" (f32.const nan)) (f32.const nan:canonical))
   121  (assert_return (invoke "f32.no_fold_zero_div" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
   122  (assert_return (invoke "f64.no_fold_zero_div" (f64.const 0.0)) (f64.const nan:canonical))
   123  (assert_return (invoke "f64.no_fold_zero_div" (f64.const -0.0)) (f64.const nan:canonical))
   124  (assert_return (invoke "f64.no_fold_zero_div" (f64.const nan)) (f64.const nan:canonical))
   125  (assert_return (invoke "f64.no_fold_zero_div" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
   126  
   127  ;; Test that x/1.0 is not folded to x.
   128  
   129  (module
   130    (func (export "f32.no_fold_div_one") (param $x f32) (result f32)
   131      (f32.div (local.get $x) (f32.const 1.0)))
   132    (func (export "f64.no_fold_div_one") (param $x f64) (result f64)
   133      (f64.div (local.get $x) (f64.const 1.0)))
   134  )
   135  
   136  (assert_return (invoke "f32.no_fold_div_one" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
   137  (assert_return (invoke "f64.no_fold_div_one" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
   138  
   139  ;; Test that x/-1.0 is not folded to -x.
   140  
   141  (module
   142    (func (export "f32.no_fold_div_neg1") (param $x f32) (result f32)
   143      (f32.div (local.get $x) (f32.const -1.0)))
   144    (func (export "f64.no_fold_div_neg1") (param $x f64) (result f64)
   145      (f64.div (local.get $x) (f64.const -1.0)))
   146  )
   147  
   148  (assert_return (invoke "f32.no_fold_div_neg1" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
   149  (assert_return (invoke "f64.no_fold_div_neg1" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
   150  
   151  ;; Test that -0.0 - x is not folded to -x.
   152  
   153  (module
   154    (func (export "f32.no_fold_neg0_sub") (param $x f32) (result f32)
   155      (f32.sub (f32.const -0.0) (local.get $x)))
   156    (func (export "f64.no_fold_neg0_sub") (param $x f64) (result f64)
   157      (f64.sub (f64.const -0.0) (local.get $x)))
   158  )
   159  
   160  (assert_return (invoke "f32.no_fold_neg0_sub" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
   161  (assert_return (invoke "f64.no_fold_neg0_sub" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
   162  
   163  ;; Test that -1.0 * x is not folded to -x.
   164  
   165  (module
   166    (func (export "f32.no_fold_neg1_mul") (param $x f32) (result f32)
   167      (f32.mul (f32.const -1.0) (local.get $x)))
   168    (func (export "f64.no_fold_neg1_mul") (param $x f64) (result f64)
   169      (f64.mul (f64.const -1.0) (local.get $x)))
   170  )
   171  
   172  (assert_return (invoke "f32.no_fold_neg1_mul" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
   173  (assert_return (invoke "f64.no_fold_neg1_mul" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
   174  
   175  ;; Test that x == x is not folded to true.
   176  
   177  (module
   178    (func (export "f32.no_fold_eq_self") (param $x f32) (result i32)
   179      (f32.eq (local.get $x) (local.get $x)))
   180    (func (export "f64.no_fold_eq_self") (param $x f64) (result i32)
   181      (f64.eq (local.get $x) (local.get $x)))
   182  )
   183  
   184  (assert_return (invoke "f32.no_fold_eq_self" (f32.const nan)) (i32.const 0))
   185  (assert_return (invoke "f64.no_fold_eq_self" (f64.const nan)) (i32.const 0))
   186  
   187  ;; Test that x != x is not folded to false.
   188  
   189  (module
   190    (func (export "f32.no_fold_ne_self") (param $x f32) (result i32)
   191      (f32.ne (local.get $x) (local.get $x)))
   192    (func (export "f64.no_fold_ne_self") (param $x f64) (result i32)
   193      (f64.ne (local.get $x) (local.get $x)))
   194  )
   195  
   196  (assert_return (invoke "f32.no_fold_ne_self" (f32.const nan)) (i32.const 1))
   197  (assert_return (invoke "f64.no_fold_ne_self" (f64.const nan)) (i32.const 1))
   198  
   199  ;; Test that x - x is not folded to 0.0.
   200  
   201  (module
   202    (func (export "f32.no_fold_sub_self") (param $x f32) (result f32)
   203      (f32.sub (local.get $x) (local.get $x)))
   204    (func (export "f64.no_fold_sub_self") (param $x f64) (result f64)
   205      (f64.sub (local.get $x) (local.get $x)))
   206  )
   207  
   208  (assert_return (invoke "f32.no_fold_sub_self" (f32.const inf)) (f32.const nan:canonical))
   209  (assert_return (invoke "f32.no_fold_sub_self" (f32.const nan)) (f32.const nan:canonical))
   210  (assert_return (invoke "f64.no_fold_sub_self" (f64.const inf)) (f64.const nan:canonical))
   211  (assert_return (invoke "f64.no_fold_sub_self" (f64.const nan)) (f64.const nan:canonical))
   212  
   213  ;; Test that x / x is not folded to 1.0.
   214  
   215  (module
   216    (func (export "f32.no_fold_div_self") (param $x f32) (result f32)
   217      (f32.div (local.get $x) (local.get $x)))
   218    (func (export "f64.no_fold_div_self") (param $x f64) (result f64)
   219      (f64.div (local.get $x) (local.get $x)))
   220  )
   221  
   222  (assert_return (invoke "f32.no_fold_div_self" (f32.const inf)) (f32.const nan:canonical))
   223  (assert_return (invoke "f32.no_fold_div_self" (f32.const nan)) (f32.const nan:canonical))
   224  (assert_return (invoke "f32.no_fold_div_self" (f32.const 0.0)) (f32.const nan:canonical))
   225  (assert_return (invoke "f32.no_fold_div_self" (f32.const -0.0)) (f32.const nan:canonical))
   226  (assert_return (invoke "f64.no_fold_div_self" (f64.const inf)) (f64.const nan:canonical))
   227  (assert_return (invoke "f64.no_fold_div_self" (f64.const nan)) (f64.const nan:canonical))
   228  (assert_return (invoke "f64.no_fold_div_self" (f64.const 0.0)) (f64.const nan:canonical))
   229  (assert_return (invoke "f64.no_fold_div_self" (f64.const -0.0)) (f64.const nan:canonical))
   230  
   231  ;; Test that x/3 is not folded to x*(1/3).
   232  
   233  (module
   234    (func (export "f32.no_fold_div_3") (param $x f32) (result f32)
   235      (f32.div (local.get $x) (f32.const 3.0)))
   236    (func (export "f64.no_fold_div_3") (param $x f64) (result f64)
   237      (f64.div (local.get $x) (f64.const 3.0)))
   238  )
   239  
   240  (assert_return (invoke "f32.no_fold_div_3" (f32.const -0x1.359c26p+50)) (f32.const -0x1.9cd032p+48))
   241  (assert_return (invoke "f32.no_fold_div_3" (f32.const -0x1.e45646p+93)) (f32.const -0x1.42e42ep+92))
   242  (assert_return (invoke "f32.no_fold_div_3" (f32.const -0x1.2a3916p-83)) (f32.const -0x1.8da172p-85))
   243  (assert_return (invoke "f32.no_fold_div_3" (f32.const -0x1.1f8b38p-124)) (f32.const -0x1.7f644ap-126))
   244  (assert_return (invoke "f32.no_fold_div_3" (f32.const -0x1.d64f64p-56)) (f32.const -0x1.398a42p-57))
   245  (assert_return (invoke "f64.no_fold_div_3" (f64.const -0x1.a8a88d29e2cc3p+632)) (f64.const -0x1.1b1b08c69732dp+631))
   246  (assert_return (invoke "f64.no_fold_div_3" (f64.const -0x1.bcf52dc950972p-167)) (f64.const -0x1.28a373db8b0f7p-168))
   247  (assert_return (invoke "f64.no_fold_div_3" (f64.const 0x1.bd3c0d989f7a4p-874)) (f64.const 0x1.28d2b3bb14fc3p-875))
   248  (assert_return (invoke "f64.no_fold_div_3" (f64.const -0x1.0138bf530a53cp+1007)) (f64.const -0x1.56f6546eb86fbp+1005))
   249  (assert_return (invoke "f64.no_fold_div_3" (f64.const 0x1.052b87f9d794dp+415)) (f64.const 0x1.5c3a0aa274c67p+413))
   250  
   251  ;; Test that (x*z)+(y*z) is not folded to (x+y)*z.
   252  
   253  (module
   254    (func (export "f32.no_factor") (param $x f32) (param $y f32) (param $z f32) (result f32)
   255      (f32.add (f32.mul (local.get $x) (local.get $z)) (f32.mul (local.get $y) (local.get $z))))
   256    (func (export "f64.no_factor") (param $x f64) (param $y f64) (param $z f64) (result f64)
   257      (f64.add (f64.mul (local.get $x) (local.get $z)) (f64.mul (local.get $y) (local.get $z))))
   258  )
   259  
   260  (assert_return (invoke "f32.no_factor" (f32.const -0x1.4e2352p+40) (f32.const -0x1.842e2cp+49) (f32.const 0x1.eea602p+59)) (f32.const -0x1.77a7dp+109))
   261  (assert_return (invoke "f32.no_factor" (f32.const -0x1.b4e7f6p-6) (f32.const 0x1.8c990cp-5) (f32.const -0x1.70cc02p-9)) (f32.const -0x1.00a342p-14))
   262  (assert_return (invoke "f32.no_factor" (f32.const -0x1.06722ep-41) (f32.const 0x1.eed3cep-64) (f32.const 0x1.5c5558p+123)) (f32.const -0x1.651aaep+82))
   263  (assert_return (invoke "f32.no_factor" (f32.const -0x1.f8c6a4p-64) (f32.const 0x1.08c806p-83) (f32.const 0x1.b5ceccp+118)) (f32.const -0x1.afa15p+55))
   264  (assert_return (invoke "f32.no_factor" (f32.const -0x1.3aaa1ep-84) (f32.const 0x1.c6d5eep-71) (f32.const 0x1.8d2924p+20)) (f32.const 0x1.60c9cep-50))
   265  (assert_return (invoke "f64.no_factor" (f64.const 0x1.3adeda9144977p-424) (f64.const 0x1.c15af887049e1p-462) (f64.const -0x1.905179c4c4778p-225)) (f64.const -0x1.ec606bcb87b1ap-649))
   266  (assert_return (invoke "f64.no_factor" (f64.const 0x1.3c84821c1d348p-662) (f64.const -0x1.4ffd4c77ad037p-1009) (f64.const -0x1.dd275335c6f4p-957)) (f64.const 0x0p+0))
   267  (assert_return (invoke "f64.no_factor" (f64.const -0x1.074f372347051p-334) (f64.const -0x1.aaeef661f4c96p-282) (f64.const -0x1.9bd34abe8696dp+479)) (f64.const 0x1.5767029593e2p+198))
   268  (assert_return (invoke "f64.no_factor" (f64.const -0x1.c4ded58a6f389p-289) (f64.const 0x1.ba6fdef5d59c9p-260) (f64.const -0x1.c1201c0470205p-253)) (f64.const -0x1.841ada2e0f184p-512))
   269  (assert_return (invoke "f64.no_factor" (f64.const 0x1.9d3688f8e375ap-608) (f64.const 0x1.bf91311588256p-579) (f64.const -0x1.1605a6b5d5ff8p+489)) (f64.const -0x1.e6118ca76af53p-90))
   270  
   271  ;; Test that (x+y)*z is not folded to (x*z)+(y*z).
   272  
   273  (module
   274    (func (export "f32.no_distribute") (param $x f32) (param $y f32) (param $z f32) (result f32)
   275      (f32.mul (f32.add (local.get $x) (local.get $y)) (local.get $z)))
   276    (func (export "f64.no_distribute") (param $x f64) (param $y f64) (param $z f64) (result f64)
   277      (f64.mul (f64.add (local.get $x) (local.get $y)) (local.get $z)))
   278  )
   279  
   280  (assert_return (invoke "f32.no_distribute" (f32.const -0x1.4e2352p+40) (f32.const -0x1.842e2cp+49) (f32.const 0x1.eea602p+59)) (f32.const -0x1.77a7d2p+109))
   281  (assert_return (invoke "f32.no_distribute" (f32.const -0x1.b4e7f6p-6) (f32.const 0x1.8c990cp-5) (f32.const -0x1.70cc02p-9)) (f32.const -0x1.00a34p-14))
   282  (assert_return (invoke "f32.no_distribute" (f32.const -0x1.06722ep-41) (f32.const 0x1.eed3cep-64) (f32.const 0x1.5c5558p+123)) (f32.const -0x1.651abp+82))
   283  (assert_return (invoke "f32.no_distribute" (f32.const -0x1.f8c6a4p-64) (f32.const 0x1.08c806p-83) (f32.const 0x1.b5ceccp+118)) (f32.const -0x1.afa14ep+55))
   284  (assert_return (invoke "f32.no_distribute" (f32.const -0x1.3aaa1ep-84) (f32.const 0x1.c6d5eep-71) (f32.const 0x1.8d2924p+20)) (f32.const 0x1.60c9ccp-50))
   285  (assert_return (invoke "f64.no_distribute" (f64.const 0x1.3adeda9144977p-424) (f64.const 0x1.c15af887049e1p-462) (f64.const -0x1.905179c4c4778p-225)) (f64.const -0x1.ec606bcb87b1bp-649))
   286  (assert_return (invoke "f64.no_distribute" (f64.const 0x1.3c84821c1d348p-662) (f64.const -0x1.4ffd4c77ad037p-1009) (f64.const -0x1.dd275335c6f4p-957)) (f64.const -0x0p+0))
   287  (assert_return (invoke "f64.no_distribute" (f64.const -0x1.074f372347051p-334) (f64.const -0x1.aaeef661f4c96p-282) (f64.const -0x1.9bd34abe8696dp+479)) (f64.const 0x1.5767029593e1fp+198))
   288  (assert_return (invoke "f64.no_distribute" (f64.const -0x1.c4ded58a6f389p-289) (f64.const 0x1.ba6fdef5d59c9p-260) (f64.const -0x1.c1201c0470205p-253)) (f64.const -0x1.841ada2e0f183p-512))
   289  (assert_return (invoke "f64.no_distribute" (f64.const 0x1.9d3688f8e375ap-608) (f64.const 0x1.bf91311588256p-579) (f64.const -0x1.1605a6b5d5ff8p+489)) (f64.const -0x1.e6118ca76af52p-90))
   290  
   291  ;; Test that x*(y/z) is not folded to (x*y)/z.
   292  
   293  (module
   294    (func (export "f32.no_regroup_div_mul") (param $x f32) (param $y f32) (param $z f32) (result f32)
   295      (f32.mul (local.get $x) (f32.div (local.get $y) (local.get $z))))
   296    (func (export "f64.no_regroup_div_mul") (param $x f64) (param $y f64) (param $z f64) (result f64)
   297      (f64.mul (local.get $x) (f64.div (local.get $y) (local.get $z))))
   298  )
   299  
   300  (assert_return (invoke "f32.no_regroup_div_mul" (f32.const -0x1.2d14a6p-115) (f32.const -0x1.575a6cp-64) (f32.const 0x1.5cee0ep-116)) (f32.const 0x1.2844cap-63))
   301  (assert_return (invoke "f32.no_regroup_div_mul" (f32.const -0x1.454738p+91) (f32.const -0x1.b28a66p-115) (f32.const -0x1.f53908p+72)) (f32.const -0x0p+0))
   302  (assert_return (invoke "f32.no_regroup_div_mul" (f32.const -0x1.6be56ep+16) (f32.const -0x1.b46fc6p-21) (f32.const -0x1.a51df6p-123)) (f32.const -0x1.792258p+118))
   303  (assert_return (invoke "f32.no_regroup_div_mul" (f32.const -0x1.c343f8p-94) (f32.const 0x1.e4d906p+73) (f32.const 0x1.be69f8p+68)) (f32.const -0x1.ea1df2p-89))
   304  (assert_return (invoke "f32.no_regroup_div_mul" (f32.const 0x1.c6ae76p+112) (f32.const 0x1.fc953cp+24) (f32.const -0x1.60b3e8p+71)) (f32.const -0x1.47d0eap+66))
   305  (assert_return (invoke "f64.no_regroup_div_mul" (f64.const 0x1.3c04b815e30bp-423) (f64.const -0x1.379646fd98127p-119) (f64.const 0x1.bddb158506031p-642)) (f64.const -0x1.b9b3301f2dd2dp+99))
   306  (assert_return (invoke "f64.no_regroup_div_mul" (f64.const 0x1.46b3a402f86d5p+337) (f64.const 0x1.6fbf1b9e1798dp-447) (f64.const -0x1.bd9704a5a6a06p+797)) (f64.const -0x0p+0))
   307  (assert_return (invoke "f64.no_regroup_div_mul" (f64.const 0x1.6c9765bb4347fp-479) (f64.const 0x1.a4af42e34a141p+902) (f64.const 0x1.d2dde70eb68f9p-448)) (f64.const inf))
   308  (assert_return (invoke "f64.no_regroup_div_mul" (f64.const -0x1.706023645be72p+480) (f64.const -0x1.6c229f7d9101dp+611) (f64.const -0x1.4d50fa68d3d9ep+836)) (f64.const -0x1.926fa3cacc651p+255))
   309  (assert_return (invoke "f64.no_regroup_div_mul" (f64.const 0x1.8cc63d8caf4c7p-599) (f64.const 0x1.8671ac4c35753p-878) (f64.const -0x1.ef35b1695e659p-838)) (f64.const -0x1.38d55f56406dp-639))
   310  
   311  ;; Test that (x*y)/z is not folded to x*(y/z).
   312  
   313  (module
   314    (func (export "f32.no_regroup_mul_div") (param $x f32) (param $y f32) (param $z f32) (result f32)
   315      (f32.div (f32.mul (local.get $x) (local.get $y)) (local.get $z)))
   316    (func (export "f64.no_regroup_mul_div") (param $x f64) (param $y f64) (param $z f64) (result f64)
   317      (f64.div (f64.mul (local.get $x) (local.get $y)) (local.get $z)))
   318  )
   319  
   320  (assert_return (invoke "f32.no_regroup_mul_div" (f32.const -0x1.2d14a6p-115) (f32.const -0x1.575a6cp-64) (f32.const 0x1.5cee0ep-116)) (f32.const 0x0p+0))
   321  (assert_return (invoke "f32.no_regroup_mul_div" (f32.const -0x1.454738p+91) (f32.const -0x1.b28a66p-115) (f32.const -0x1.f53908p+72)) (f32.const -0x1.1a00e8p-96))
   322  (assert_return (invoke "f32.no_regroup_mul_div" (f32.const -0x1.6be56ep+16) (f32.const -0x1.b46fc6p-21) (f32.const -0x1.a51df6p-123)) (f32.const -0x1.79225ap+118))
   323  (assert_return (invoke "f32.no_regroup_mul_div" (f32.const -0x1.c343f8p-94) (f32.const 0x1.e4d906p+73) (f32.const 0x1.be69f8p+68)) (f32.const -0x1.ea1df4p-89))
   324  (assert_return (invoke "f32.no_regroup_mul_div" (f32.const 0x1.c6ae76p+112) (f32.const 0x1.fc953cp+24) (f32.const -0x1.60b3e8p+71)) (f32.const -inf))
   325  (assert_return (invoke "f64.no_regroup_mul_div" (f64.const 0x1.3c04b815e30bp-423) (f64.const -0x1.379646fd98127p-119) (f64.const 0x1.bddb158506031p-642)) (f64.const -0x1.b9b3301f2dd2ep+99))
   326  (assert_return (invoke "f64.no_regroup_mul_div" (f64.const 0x1.46b3a402f86d5p+337) (f64.const 0x1.6fbf1b9e1798dp-447) (f64.const -0x1.bd9704a5a6a06p+797)) (f64.const -0x1.0da0b6328e09p-907))
   327  (assert_return (invoke "f64.no_regroup_mul_div" (f64.const 0x1.6c9765bb4347fp-479) (f64.const 0x1.a4af42e34a141p+902) (f64.const 0x1.d2dde70eb68f9p-448)) (f64.const 0x1.4886b6d9a9a79p+871))
   328  (assert_return (invoke "f64.no_regroup_mul_div" (f64.const -0x1.706023645be72p+480) (f64.const -0x1.6c229f7d9101dp+611) (f64.const -0x1.4d50fa68d3d9ep+836)) (f64.const -inf))
   329  (assert_return (invoke "f64.no_regroup_mul_div" (f64.const 0x1.8cc63d8caf4c7p-599) (f64.const 0x1.8671ac4c35753p-878) (f64.const -0x1.ef35b1695e659p-838)) (f64.const -0x0p+0))
   330  
   331  ;; Test that x+y+z+w is not reassociated.
   332  
   333  (module
   334    (func (export "f32.no_reassociate_add") (param $x f32) (param $y f32) (param $z f32) (param $w f32) (result f32)
   335      (f32.add (f32.add (f32.add (local.get $x) (local.get $y)) (local.get $z)) (local.get $w)))
   336    (func (export "f64.no_reassociate_add") (param $x f64) (param $y f64) (param $z f64) (param $w f64) (result f64)
   337      (f64.add (f64.add (f64.add (local.get $x) (local.get $y)) (local.get $z)) (local.get $w)))
   338  )
   339  
   340  (assert_return (invoke "f32.no_reassociate_add" (f32.const -0x1.5f7ddcp+44) (f32.const 0x1.854e1p+34) (f32.const -0x1.b2068cp+47) (f32.const -0x1.209692p+41)) (f32.const -0x1.e26c76p+47))
   341  (assert_return (invoke "f32.no_reassociate_add" (f32.const 0x1.da3b78p-9) (f32.const -0x1.4312fap-7) (f32.const 0x1.0395e6p-4) (f32.const -0x1.6d5ea6p-7)) (f32.const 0x1.78b31ap-5))
   342  (assert_return (invoke "f32.no_reassociate_add" (f32.const -0x1.fdb93ap+34) (f32.const -0x1.b6fce6p+41) (f32.const 0x1.c131d8p+44) (f32.const 0x1.8835b6p+38)) (f32.const 0x1.8ff3a2p+44))
   343  (assert_return (invoke "f32.no_reassociate_add" (f32.const 0x1.1739fcp+47) (f32.const 0x1.a4b186p+49) (f32.const -0x1.0c623cp+35) (f32.const 0x1.16a102p+51)) (f32.const 0x1.913ff6p+51))
   344  (assert_return (invoke "f32.no_reassociate_add" (f32.const 0x1.733cfap+108) (f32.const -0x1.38d30cp+108) (f32.const 0x1.2f5854p+105) (f32.const -0x1.ccb058p+94)) (f32.const 0x1.813716p+106))
   345  (assert_return (invoke "f64.no_reassociate_add" (f64.const -0x1.697a4d9ff19a6p+841) (f64.const 0x1.b305466238397p+847) (f64.const 0x1.e0b2d9bfb4e72p+855) (f64.const -0x1.6e1f3ae2b06bbp+857)) (f64.const -0x1.eb0e5936f087ap+856))
   346  (assert_return (invoke "f64.no_reassociate_add" (f64.const 0x1.00ef6746b30e1p-543) (f64.const 0x1.cc1cfafdf3fe1p-544) (f64.const -0x1.f7726df3ecba6p-543) (f64.const -0x1.b26695f99d307p-594)) (f64.const -0x1.074892e3fad76p-547))
   347  (assert_return (invoke "f64.no_reassociate_add" (f64.const -0x1.e807b3bd6d854p+440) (f64.const 0x1.cedae26c2c5fp+407) (f64.const -0x1.00ab6e1442541p+437) (f64.const 0x1.28538a55997bdp+397)) (f64.const -0x1.040e90bf871ebp+441))
   348  (assert_return (invoke "f64.no_reassociate_add" (f64.const -0x1.ba2b6f35a2402p-317) (f64.const 0x1.ad1c3fea7cd9ep-307) (f64.const -0x1.93aace2bf1261p-262) (f64.const 0x1.9fddbe472847ep-260)) (f64.const 0x1.3af30abc2c01bp-260))
   349  (assert_return (invoke "f64.no_reassociate_add" (f64.const -0x1.ccb9c6092fb1dp+641) (f64.const -0x1.4b7c28c108244p+614) (f64.const 0x1.8a7cefef4bde1p+646) (f64.const -0x1.901b28b08b482p+644)) (f64.const 0x1.1810579194126p+646))
   350  
   351  ;; Test that x*y*z*w is not reassociated.
   352  
   353  (module
   354    (func (export "f32.no_reassociate_mul") (param $x f32) (param $y f32) (param $z f32) (param $w f32) (result f32)
   355      (f32.mul (f32.mul (f32.mul (local.get $x) (local.get $y)) (local.get $z)) (local.get $w)))
   356    (func (export "f64.no_reassociate_mul") (param $x f64) (param $y f64) (param $z f64) (param $w f64) (result f64)
   357      (f64.mul (f64.mul (f64.mul (local.get $x) (local.get $y)) (local.get $z)) (local.get $w)))
   358  )
   359  
   360  (assert_return (invoke "f32.no_reassociate_mul" (f32.const 0x1.950ba8p-116) (f32.const 0x1.efdacep-33) (f32.const -0x1.5f9bcp+102) (f32.const 0x1.f04508p-56)) (f32.const -0x1.ff356ep-101))
   361  (assert_return (invoke "f32.no_reassociate_mul" (f32.const 0x1.5990aep-56) (f32.const -0x1.7dfb04p+102) (f32.const -0x1.4f774ap-125) (f32.const -0x1.595fe6p+70)) (f32.const -0x1.c7c8fcp-8))
   362  (assert_return (invoke "f32.no_reassociate_mul" (f32.const 0x1.6ad9a4p-48) (f32.const -0x1.9138aap+55) (f32.const -0x1.4a774ep-40) (f32.const 0x1.1ff08p+76)) (f32.const 0x1.9cd8ecp+44))
   363  (assert_return (invoke "f32.no_reassociate_mul" (f32.const 0x1.e1caecp-105) (f32.const 0x1.af0dd2p+77) (f32.const -0x1.016eep+56) (f32.const -0x1.ab70d6p+59)) (f32.const 0x1.54870ep+89))
   364  (assert_return (invoke "f32.no_reassociate_mul" (f32.const -0x1.3b1dcp-99) (f32.const 0x1.4e5a34p-49) (f32.const -0x1.38ba5ap+3) (f32.const 0x1.7fb8eep+59)) (f32.const 0x1.5bbf98p-85))
   365  (assert_return (invoke "f64.no_reassociate_mul" (f64.const -0x1.e7842ab7181p-667) (f64.const -0x1.fabf40ceeceafp+990) (f64.const -0x1.1a38a825ab01ap-376) (f64.const -0x1.27e8ea469b14fp+664)) (f64.const 0x1.336eb428af4f3p+613))
   366  (assert_return (invoke "f64.no_reassociate_mul" (f64.const 0x1.4ca2292a6acbcp+454) (f64.const 0x1.6ffbab850089ap-516) (f64.const -0x1.547c32e1f5b93p-899) (f64.const -0x1.c7571d9388375p+540)) (f64.const 0x1.1ac796954fc1p-419))
   367  (assert_return (invoke "f64.no_reassociate_mul" (f64.const 0x1.73881a52e0401p-501) (f64.const -0x1.1b68dd9efb1a7p+788) (f64.const 0x1.d1c5e6a3eb27cp-762) (f64.const -0x1.56cb2fcc7546fp+88)) (f64.const 0x1.f508db92c34efp-386))
   368  (assert_return (invoke "f64.no_reassociate_mul" (f64.const 0x1.2efa87859987cp+692) (f64.const 0x1.68e4373e241p-423) (f64.const 0x1.4e2d0fb383a57p+223) (f64.const -0x1.301d3265c737bp-23)) (f64.const -0x1.4b2b6c393f30cp+470))
   369  (assert_return (invoke "f64.no_reassociate_mul" (f64.const 0x1.1013f7498b95fp-234) (f64.const 0x1.d2d1c36fff138p-792) (f64.const -0x1.cbf1824ea7bfdp+728) (f64.const -0x1.440da9c8b836dp-599)) (f64.const 0x1.1a16512881c91p-895))
   370  
   371  ;; Test that x/0 is not folded away.
   372  
   373  (module
   374    (func (export "f32.no_fold_div_0") (param $x f32) (result f32)
   375      (f32.div (local.get $x) (f32.const 0.0)))
   376    (func (export "f64.no_fold_div_0") (param $x f64) (result f64)
   377      (f64.div (local.get $x) (f64.const 0.0)))
   378  )
   379  
   380  (assert_return (invoke "f32.no_fold_div_0" (f32.const 1.0)) (f32.const inf))
   381  (assert_return (invoke "f32.no_fold_div_0" (f32.const -1.0)) (f32.const -inf))
   382  (assert_return (invoke "f32.no_fold_div_0" (f32.const inf)) (f32.const inf))
   383  (assert_return (invoke "f32.no_fold_div_0" (f32.const -inf)) (f32.const -inf))
   384  (assert_return (invoke "f32.no_fold_div_0" (f32.const 0)) (f32.const nan:canonical))
   385  (assert_return (invoke "f32.no_fold_div_0" (f32.const -0)) (f32.const nan:canonical))
   386  (assert_return (invoke "f32.no_fold_div_0" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
   387  (assert_return (invoke "f32.no_fold_div_0" (f32.const nan)) (f32.const nan:canonical))
   388  (assert_return (invoke "f64.no_fold_div_0" (f64.const 1.0)) (f64.const inf))
   389  (assert_return (invoke "f64.no_fold_div_0" (f64.const -1.0)) (f64.const -inf))
   390  (assert_return (invoke "f64.no_fold_div_0" (f64.const inf)) (f64.const inf))
   391  (assert_return (invoke "f64.no_fold_div_0" (f64.const -inf)) (f64.const -inf))
   392  (assert_return (invoke "f64.no_fold_div_0" (f64.const 0)) (f64.const nan:canonical))
   393  (assert_return (invoke "f64.no_fold_div_0" (f64.const -0)) (f64.const nan:canonical))
   394  (assert_return (invoke "f64.no_fold_div_0" (f64.const nan)) (f64.const nan:canonical))
   395  (assert_return (invoke "f64.no_fold_div_0" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
   396  
   397  ;; Test that x/-0 is not folded away.
   398  
   399  (module
   400    (func (export "f32.no_fold_div_neg0") (param $x f32) (result f32)
   401      (f32.div (local.get $x) (f32.const -0.0)))
   402    (func (export "f64.no_fold_div_neg0") (param $x f64) (result f64)
   403      (f64.div (local.get $x) (f64.const -0.0)))
   404  )
   405  
   406  (assert_return (invoke "f32.no_fold_div_neg0" (f32.const 1.0)) (f32.const -inf))
   407  (assert_return (invoke "f32.no_fold_div_neg0" (f32.const -1.0)) (f32.const inf))
   408  (assert_return (invoke "f32.no_fold_div_neg0" (f32.const inf)) (f32.const -inf))
   409  (assert_return (invoke "f32.no_fold_div_neg0" (f32.const -inf)) (f32.const inf))
   410  (assert_return (invoke "f32.no_fold_div_neg0" (f32.const 0)) (f32.const nan:canonical))
   411  (assert_return (invoke "f32.no_fold_div_neg0" (f32.const -0)) (f32.const nan:canonical))
   412  (assert_return (invoke "f32.no_fold_div_neg0" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
   413  (assert_return (invoke "f32.no_fold_div_neg0" (f32.const nan)) (f32.const nan:canonical))
   414  (assert_return (invoke "f64.no_fold_div_neg0" (f64.const 1.0)) (f64.const -inf))
   415  (assert_return (invoke "f64.no_fold_div_neg0" (f64.const -1.0)) (f64.const inf))
   416  (assert_return (invoke "f64.no_fold_div_neg0" (f64.const inf)) (f64.const -inf))
   417  (assert_return (invoke "f64.no_fold_div_neg0" (f64.const -inf)) (f64.const inf))
   418  (assert_return (invoke "f64.no_fold_div_neg0" (f64.const 0)) (f64.const nan:canonical))
   419  (assert_return (invoke "f64.no_fold_div_neg0" (f64.const -0)) (f64.const nan:canonical))
   420  (assert_return (invoke "f64.no_fold_div_neg0" (f64.const nan)) (f64.const nan:canonical))
   421  (assert_return (invoke "f64.no_fold_div_neg0" (f64.const nan:0x4000000000000)) (f64.const nan:arithmetic))
   422  
   423  ;; Test that sqrt(x*x+y*y) is not folded to hypot.
   424  
   425  (module
   426    (func (export "f32.no_fold_to_hypot") (param $x f32) (param $y f32) (result f32)
   427      (f32.sqrt (f32.add (f32.mul (local.get $x) (local.get $x))
   428                         (f32.mul (local.get $y) (local.get $y)))))
   429    (func (export "f64.no_fold_to_hypot") (param $x f64) (param $y f64) (result f64)
   430      (f64.sqrt (f64.add (f64.mul (local.get $x) (local.get $x))
   431                         (f64.mul (local.get $y) (local.get $y)))))
   432  )
   433  
   434  (assert_return (invoke "f32.no_fold_to_hypot" (f32.const 0x1.c2f338p-81) (f32.const 0x1.401b5ep-68)) (f32.const 0x1.401cccp-68))
   435  (assert_return (invoke "f32.no_fold_to_hypot" (f32.const -0x1.c38d1p-71) (f32.const -0x1.359ddp-107)) (f32.const 0x1.c36a62p-71))
   436  (assert_return (invoke "f32.no_fold_to_hypot" (f32.const -0x1.99e0cap-114) (f32.const -0x1.ed0c6cp-69)) (f32.const 0x1.ed0e48p-69))
   437  (assert_return (invoke "f32.no_fold_to_hypot" (f32.const -0x1.1b6ceap+5) (f32.const 0x1.5440bep+17)) (f32.const 0x1.5440cp+17))
   438  (assert_return (invoke "f32.no_fold_to_hypot" (f32.const 0x1.8f019ep-76) (f32.const -0x1.182308p-71)) (f32.const 0x1.17e2bcp-71))
   439  (assert_return (invoke "f64.no_fold_to_hypot" (f64.const 0x1.1a0ac4f7c8711p-636) (f64.const 0x1.1372ebafff551p-534)) (f64.const 0x1.13463fa37014ep-534))
   440  (assert_return (invoke "f64.no_fold_to_hypot" (f64.const 0x1.b793512167499p+395) (f64.const -0x1.11cbc52af4c36p+410)) (f64.const 0x1.11cbc530783a2p+410))
   441  (assert_return (invoke "f64.no_fold_to_hypot" (f64.const 0x1.76777f44ff40bp-536) (f64.const -0x1.c3896e4dc1fbp-766)) (f64.const 0x1.8p-536))
   442  (assert_return (invoke "f64.no_fold_to_hypot" (f64.const -0x1.889ac72cc6b5dp-521) (f64.const 0x1.8d7084e659f3bp-733)) (f64.const 0x1.889ac72ca843ap-521))
   443  (assert_return (invoke "f64.no_fold_to_hypot" (f64.const 0x1.5ee588c02cb08p-670) (f64.const -0x1.05ce25788d9ecp-514)) (f64.const 0x1.05ce25788d9dfp-514))
   444  
   445  ;; Test that 1.0/x isn't approximated.
   446  
   447  (module
   448    (func (export "f32.no_approximate_reciprocal") (param $x f32) (result f32)
   449      (f32.div (f32.const 1.0) (local.get $x)))
   450  )
   451  
   452  (assert_return (invoke "f32.no_approximate_reciprocal" (f32.const -0x1.2900b6p-10)) (f32.const -0x1.b950d4p+9))
   453  (assert_return (invoke "f32.no_approximate_reciprocal" (f32.const 0x1.e7212p+127)) (f32.const 0x1.0d11f8p-128))
   454  (assert_return (invoke "f32.no_approximate_reciprocal" (f32.const -0x1.42a466p-93)) (f32.const -0x1.963ee6p+92))
   455  (assert_return (invoke "f32.no_approximate_reciprocal" (f32.const 0x1.5d0c32p+76)) (f32.const 0x1.778362p-77))
   456  (assert_return (invoke "f32.no_approximate_reciprocal" (f32.const -0x1.601de2p-82)) (f32.const -0x1.743d7ep+81))
   457  
   458  ;; Test that 1.0/sqrt(x) isn't approximated or fused.
   459  
   460  (module
   461    (func (export "f32.no_approximate_reciprocal_sqrt") (param $x f32) (result f32)
   462      (f32.div (f32.const 1.0) (f32.sqrt (local.get $x))))
   463    (func (export "f64.no_fuse_reciprocal_sqrt") (param $x f64) (result f64)
   464      (f64.div (f64.const 1.0) (f64.sqrt (local.get $x))))
   465  )
   466  
   467  (assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.6af12ap-43)) (f32.const 0x1.300ed4p+21))
   468  (assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.e82fc6p-8)) (f32.const 0x1.72c376p+3))
   469  (assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.b9fa9cp-66)) (f32.const 0x1.85a9bap+32))
   470  (assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.f4f546p-44)) (f32.const 0x1.6e01c2p+21))
   471  (assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.5da7aap-86)) (f32.const 0x1.b618cap+42))
   472  
   473  (assert_return (invoke "f64.no_fuse_reciprocal_sqrt" (f64.const 0x1.1568a63b55fa3p+889)) (f64.const 0x1.5bc9c74c9952p-445))
   474  (assert_return (invoke "f64.no_fuse_reciprocal_sqrt" (f64.const 0x1.239fcd0939cafp+311)) (f64.const 0x1.5334a922b4818p-156))
   475  (assert_return (invoke "f64.no_fuse_reciprocal_sqrt" (f64.const 0x1.6e36a24e11054p+104)) (f64.const 0x1.ac13f20977f29p-53))
   476  (assert_return (invoke "f64.no_fuse_reciprocal_sqrt" (f64.const 0x1.23ee173219f83p+668)) (f64.const 0x1.df753e055862dp-335))
   477  (assert_return (invoke "f64.no_fuse_reciprocal_sqrt" (f64.const 0x1.b30f74caf9babp+146)) (f64.const 0x1.88bfc3d1764a9p-74))
   478  
   479  ;; Test that sqrt(1.0/x) isn't approximated.
   480  
   481  (module
   482    (func (export "f32.no_approximate_sqrt_reciprocal") (param $x f32) (result f32)
   483      (f32.sqrt (f32.div (f32.const 1.0) (local.get $x))))
   484  )
   485  
   486  (assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.a4c986p+60)) (f32.const 0x1.8f5ac6p-31))
   487  (assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.50511ep-9)) (f32.const 0x1.3bdd46p+4))
   488  (assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.125ec2p+69)) (f32.const 0x1.5db572p-35))
   489  (assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.ba4c5p+13)) (f32.const 0x1.136f16p-7))
   490  (assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.4a5be2p+104)) (f32.const 0x1.c2b5bp-53))
   491  
   492  ;; Test that converting i32/i64 to f32/f64 and back isn't folded away.
   493  
   494  (module
   495    (func (export "i32.no_fold_f32_s") (param i32) (result i32)
   496      (i32.trunc_f32_s (f32.convert_i32_s (local.get 0))))
   497    (func (export "i32.no_fold_f32_u") (param i32) (result i32)
   498      (i32.trunc_f32_u (f32.convert_i32_u (local.get 0))))
   499    (func (export "i64.no_fold_f64_s") (param i64) (result i64)
   500      (i64.trunc_f64_s (f64.convert_i64_s (local.get 0))))
   501    (func (export "i64.no_fold_f64_u") (param i64) (result i64)
   502      (i64.trunc_f64_u (f64.convert_i64_u (local.get 0))))
   503  )
   504  
   505  (assert_return (invoke "i32.no_fold_f32_s" (i32.const 0x1000000)) (i32.const 0x1000000))
   506  (assert_return (invoke "i32.no_fold_f32_s" (i32.const 0x1000001)) (i32.const 0x1000000))
   507  (assert_return (invoke "i32.no_fold_f32_s" (i32.const 0xf0000010)) (i32.const 0xf0000010))
   508  
   509  (assert_return (invoke "i32.no_fold_f32_u" (i32.const 0x1000000)) (i32.const 0x1000000))
   510  (assert_return (invoke "i32.no_fold_f32_u" (i32.const 0x1000001)) (i32.const 0x1000000))
   511  (assert_return (invoke "i32.no_fold_f32_u" (i32.const 0xf0000010)) (i32.const 0xf0000000))
   512  
   513  (assert_return (invoke "i64.no_fold_f64_s" (i64.const 0x20000000000000)) (i64.const 0x20000000000000))
   514  (assert_return (invoke "i64.no_fold_f64_s" (i64.const 0x20000000000001)) (i64.const 0x20000000000000))
   515  (assert_return (invoke "i64.no_fold_f64_s" (i64.const 0xf000000000000400)) (i64.const 0xf000000000000400))
   516  
   517  (assert_return (invoke "i64.no_fold_f64_u" (i64.const 0x20000000000000)) (i64.const 0x20000000000000))
   518  (assert_return (invoke "i64.no_fold_f64_u" (i64.const 0x20000000000001)) (i64.const 0x20000000000000))
   519  (assert_return (invoke "i64.no_fold_f64_u" (i64.const 0xf000000000000400)) (i64.const 0xf000000000000000))
   520  
   521  ;; Test that x+y-y is not folded to x.
   522  
   523  (module
   524    (func (export "f32.no_fold_add_sub") (param $x f32) (param $y f32) (result f32)
   525      (f32.sub (f32.add (local.get $x) (local.get $y)) (local.get $y)))
   526    (func (export "f64.no_fold_add_sub") (param $x f64) (param $y f64) (result f64)
   527      (f64.sub (f64.add (local.get $x) (local.get $y)) (local.get $y)))
   528  )
   529  
   530  (assert_return (invoke "f32.no_fold_add_sub" (f32.const 0x1.b553e4p-47) (f32.const -0x1.67db2cp-26)) (f32.const 0x1.cp-47))
   531  (assert_return (invoke "f32.no_fold_add_sub" (f32.const -0x1.a884dp-23) (f32.const 0x1.f2ae1ep-19)) (f32.const -0x1.a884ep-23))
   532  (assert_return (invoke "f32.no_fold_add_sub" (f32.const -0x1.fc04fp+82) (f32.const -0x1.65403ap+101)) (f32.const -0x1p+83))
   533  (assert_return (invoke "f32.no_fold_add_sub" (f32.const 0x1.870fa2p-78) (f32.const 0x1.c54916p-56)) (f32.const 0x1.8p-78))
   534  (assert_return (invoke "f32.no_fold_add_sub" (f32.const -0x1.17e966p-108) (f32.const -0x1.5fa61ap-84)) (f32.const -0x1p-107))
   535  
   536  (assert_return (invoke "f64.no_fold_add_sub" (f64.const -0x1.1053ea172dba8p-874) (f64.const 0x1.113c413408ac8p-857)) (f64.const -0x1.1053ea172p-874))
   537  (assert_return (invoke "f64.no_fold_add_sub" (f64.const 0x1.e377d54807972p-546) (f64.const 0x1.040a0a4d1ff7p-526)) (f64.const 0x1.e377d548p-546))
   538  (assert_return (invoke "f64.no_fold_add_sub" (f64.const -0x1.75f53cd926b62p-30) (f64.const -0x1.66b176e602bb5p-3)) (f64.const -0x1.75f53dp-30))
   539  (assert_return (invoke "f64.no_fold_add_sub" (f64.const -0x1.c450ff28332ap-341) (f64.const 0x1.15a5855023baep-305)) (f64.const -0x1.c451p-341))
   540  (assert_return (invoke "f64.no_fold_add_sub" (f64.const -0x1.1ad4a596d3ea8p-619) (f64.const -0x1.17d81a41c0ea8p-588)) (f64.const -0x1.1ad4a8p-619))
   541  
   542  ;; Test that x-y+y is not folded to x.
   543  
   544  (module
   545    (func (export "f32.no_fold_sub_add") (param $x f32) (param $y f32) (result f32)
   546      (f32.add (f32.sub (local.get $x) (local.get $y)) (local.get $y)))
   547    (func (export "f64.no_fold_sub_add") (param $x f64) (param $y f64) (result f64)
   548      (f64.add (f64.sub (local.get $x) (local.get $y)) (local.get $y)))
   549  )
   550  
   551  (assert_return (invoke "f32.no_fold_sub_add" (f32.const -0x1.523cb8p+9) (f32.const 0x1.93096cp+8)) (f32.const -0x1.523cbap+9))
   552  (assert_return (invoke "f32.no_fold_sub_add" (f32.const -0x1.a31a1p-111) (f32.const 0x1.745efp-95)) (f32.const -0x1.a4p-111))
   553  (assert_return (invoke "f32.no_fold_sub_add" (f32.const 0x1.3d5328p+26) (f32.const 0x1.58567p+35)) (f32.const 0x1.3d54p+26))
   554  (assert_return (invoke "f32.no_fold_sub_add" (f32.const 0x1.374e26p-39) (f32.const -0x1.66a5p-27)) (f32.const 0x1.374p-39))
   555  (assert_return (invoke "f32.no_fold_sub_add" (f32.const 0x1.320facp-3) (f32.const -0x1.ac069ap+14)) (f32.const 0x1.34p-3))
   556  
   557  (assert_return (invoke "f64.no_fold_sub_add" (f64.const 0x1.8f92aad2c9b8dp+255) (f64.const -0x1.08cd4992266cbp+259)) (f64.const 0x1.8f92aad2c9b9p+255))
   558  (assert_return (invoke "f64.no_fold_sub_add" (f64.const 0x1.5aaff55742c8bp-666) (f64.const 0x1.8f5f47181f46dp-647)) (f64.const 0x1.5aaff5578p-666))
   559  (assert_return (invoke "f64.no_fold_sub_add" (f64.const 0x1.21bc52967a98dp+251) (f64.const -0x1.fcffaa32d0884p+300)) (f64.const 0x1.2p+251))
   560  (assert_return (invoke "f64.no_fold_sub_add" (f64.const 0x1.9c78361f47374p-26) (f64.const -0x1.69d69f4edc61cp-13)) (f64.const 0x1.9c78361f48p-26))
   561  (assert_return (invoke "f64.no_fold_sub_add" (f64.const 0x1.4dbe68e4afab2p-367) (f64.const -0x1.dc24e5b39cd02p-361)) (f64.const 0x1.4dbe68e4afacp-367))
   562  
   563  ;; Test that x*y/y is not folded to x.
   564  
   565  (module
   566    (func (export "f32.no_fold_mul_div") (param $x f32) (param $y f32) (result f32)
   567      (f32.div (f32.mul (local.get $x) (local.get $y)) (local.get $y)))
   568    (func (export "f64.no_fold_mul_div") (param $x f64) (param $y f64) (result f64)
   569      (f64.div (f64.mul (local.get $x) (local.get $y)) (local.get $y)))
   570  )
   571  
   572  (assert_return (invoke "f32.no_fold_mul_div" (f32.const -0x1.cd859ap+54) (f32.const 0x1.6ca936p-47)) (f32.const -0x1.cd8598p+54))
   573  (assert_return (invoke "f32.no_fold_mul_div" (f32.const -0x1.0b56b8p-26) (f32.const 0x1.48264cp-106)) (f32.const -0x1.0b56a4p-26))
   574  (assert_return (invoke "f32.no_fold_mul_div" (f32.const -0x1.e7555cp-48) (f32.const -0x1.9161cp+48)) (f32.const -0x1.e7555ap-48))
   575  (assert_return (invoke "f32.no_fold_mul_div" (f32.const 0x1.aaa50ep+52) (f32.const -0x1.dfb39ep+60)) (f32.const 0x1.aaa50cp+52))
   576  (assert_return (invoke "f32.no_fold_mul_div" (f32.const -0x1.2b7dfap-92) (f32.const -0x1.7c4ca6p-37)) (f32.const -0x1.2b7dfep-92))
   577  
   578  (assert_return (invoke "f64.no_fold_mul_div" (f64.const -0x1.3d79ff4118a1ap-837) (f64.const -0x1.b8b5dda31808cp-205)) (f64.const -0x1.3d79ff412263ep-837))
   579  (assert_return (invoke "f64.no_fold_mul_div" (f64.const 0x1.f894d1ee6b3a4p+384) (f64.const 0x1.8c2606d03d58ap+585)) (f64.const 0x1.f894d1ee6b3a5p+384))
   580  (assert_return (invoke "f64.no_fold_mul_div" (f64.const -0x1.a022260acc993p+238) (f64.const -0x1.5fbc128fc8e3cp-552)) (f64.const -0x1.a022260acc992p+238))
   581  (assert_return (invoke "f64.no_fold_mul_div" (f64.const 0x1.9d4b8ed174f54p-166) (f64.const 0x1.ee3d467aeeac6p-906)) (f64.const 0x1.8dcc95a053b2bp-166))
   582  (assert_return (invoke "f64.no_fold_mul_div" (f64.const -0x1.e95ea897cdcd4p+660) (f64.const -0x1.854d5df085f2ep-327)) (f64.const -0x1.e95ea897cdcd5p+660))
   583  
   584  ;; Test that x/y*y is not folded to x.
   585  
   586  (module
   587    (func (export "f32.no_fold_div_mul") (param $x f32) (param $y f32) (result f32)
   588      (f32.mul (f32.div (local.get $x) (local.get $y)) (local.get $y)))
   589    (func (export "f64.no_fold_div_mul") (param $x f64) (param $y f64) (result f64)
   590      (f64.mul (f64.div (local.get $x) (local.get $y)) (local.get $y)))
   591  )
   592  
   593  (assert_return (invoke "f32.no_fold_div_mul" (f32.const -0x1.dc6364p+38) (f32.const 0x1.d630ecp+29)) (f32.const -0x1.dc6362p+38))
   594  (assert_return (invoke "f32.no_fold_div_mul" (f32.const -0x1.1f9836p-52) (f32.const -0x1.16c4e4p-18)) (f32.const -0x1.1f9838p-52))
   595  (assert_return (invoke "f32.no_fold_div_mul" (f32.const 0x1.c5972cp-126) (f32.const -0x1.d6659ep+7)) (f32.const 0x1.c5980ep-126))
   596  (assert_return (invoke "f32.no_fold_div_mul" (f32.const -0x1.2e3a9ep-74) (f32.const -0x1.353994p+59)) (f32.const -0x1.2e3a4p-74))
   597  (assert_return (invoke "f32.no_fold_div_mul" (f32.const 0x1.d96b82p-98) (f32.const 0x1.95d908p+27)) (f32.const 0x1.d96b84p-98))
   598  
   599  (assert_return (invoke "f64.no_fold_div_mul" (f64.const 0x1.d01f913a52481p-876) (f64.const -0x1.2cd0668b28344p+184)) (f64.const 0x1.d020daf71cdcp-876))
   600  (assert_return (invoke "f64.no_fold_div_mul" (f64.const -0x1.81cb7d400918dp-714) (f64.const 0x1.7caa643586d6ep-53)) (f64.const -0x1.81cb7d400918ep-714))
   601  (assert_return (invoke "f64.no_fold_div_mul" (f64.const -0x1.66904c97b5c8ep-145) (f64.const 0x1.5c3481592ad4cp+428)) (f64.const -0x1.66904c97b5c8dp-145))
   602  (assert_return (invoke "f64.no_fold_div_mul" (f64.const -0x1.e75859d2f0765p-278) (f64.const -0x1.5f19b6ab497f9p+283)) (f64.const -0x1.e75859d2f0764p-278))
   603  (assert_return (invoke "f64.no_fold_div_mul" (f64.const -0x1.515fe9c3b5f5p+620) (f64.const 0x1.36be869c99f7ap+989)) (f64.const -0x1.515fe9c3b5f4fp+620))
   604  
   605  ;; Test that x/2*2 is not folded to x.
   606  
   607  (module
   608    (func (export "f32.no_fold_div2_mul2") (param $x f32) (result f32)
   609      (f32.mul (f32.div (local.get $x) (f32.const 2.0)) (f32.const 2.0)))
   610    (func (export "f64.no_fold_div2_mul2") (param $x f64) (result f64)
   611      (f64.mul (f64.div (local.get $x) (f64.const 2.0)) (f64.const 2.0)))
   612  )
   613  
   614  (assert_return (invoke "f32.no_fold_div2_mul2" (f32.const 0x1.fffffep-126)) (f32.const 0x1p-125))
   615  (assert_return (invoke "f64.no_fold_div2_mul2" (f64.const 0x1.fffffffffffffp-1022)) (f64.const 0x1p-1021))
   616  
   617  ;; Test that promote(demote(x)) is not folded to x.
   618  
   619  (module
   620    (func (export "no_fold_demote_promote") (param $x f64) (result f64)
   621      (f64.promote_f32 (f32.demote_f64 (local.get $x))))
   622  )
   623  
   624  (assert_return (invoke "no_fold_demote_promote" (f64.const -0x1.dece272390f5dp-133)) (f64.const -0x1.decep-133))
   625  (assert_return (invoke "no_fold_demote_promote" (f64.const -0x1.19e6c79938a6fp-85)) (f64.const -0x1.19e6c8p-85))
   626  (assert_return (invoke "no_fold_demote_promote" (f64.const 0x1.49b297ec44dc1p+107)) (f64.const 0x1.49b298p+107))
   627  (assert_return (invoke "no_fold_demote_promote" (f64.const -0x1.74f5bd865163p-88)) (f64.const -0x1.74f5bep-88))
   628  (assert_return (invoke "no_fold_demote_promote" (f64.const 0x1.26d675662367ep+104)) (f64.const 0x1.26d676p+104))
   629  
   630  ;; Test that demote(promote(x)) is not folded to x, and aside from NaN is
   631  ;; bit-preserving.
   632  
   633  (module
   634    (func (export "no_fold_promote_demote") (param $x f32) (result f32)
   635      (f32.demote_f64 (f64.promote_f32 (local.get $x))))
   636  )
   637  
   638  (assert_return (invoke "no_fold_promote_demote" (f32.const nan:0x200000)) (f32.const nan:arithmetic))
   639  (assert_return (invoke "no_fold_promote_demote" (f32.const 0x0p+0)) (f32.const 0x0p+0))
   640  (assert_return (invoke "no_fold_promote_demote" (f32.const -0x0p+0)) (f32.const -0x0p+0))
   641  (assert_return (invoke "no_fold_promote_demote" (f32.const 0x1p-149)) (f32.const 0x1p-149))
   642  (assert_return (invoke "no_fold_promote_demote" (f32.const -0x1p-149)) (f32.const -0x1p-149))
   643  (assert_return (invoke "no_fold_promote_demote" (f32.const 0x1.fffffcp-127)) (f32.const 0x1.fffffcp-127))
   644  (assert_return (invoke "no_fold_promote_demote" (f32.const -0x1.fffffcp-127)) (f32.const -0x1.fffffcp-127))
   645  (assert_return (invoke "no_fold_promote_demote" (f32.const 0x1p-126)) (f32.const 0x1p-126))
   646  (assert_return (invoke "no_fold_promote_demote" (f32.const -0x1p-126)) (f32.const -0x1p-126))
   647  (assert_return (invoke "no_fold_promote_demote" (f32.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127))
   648  (assert_return (invoke "no_fold_promote_demote" (f32.const -0x1.fffffep+127)) (f32.const -0x1.fffffep+127))
   649  (assert_return (invoke "no_fold_promote_demote" (f32.const inf)) (f32.const inf))
   650  (assert_return (invoke "no_fold_promote_demote" (f32.const -inf)) (f32.const -inf))
   651  
   652  ;; Test that demote(x+promote(y)) is not folded to demote(x)+y.
   653  
   654  (module
   655    (func (export "no_demote_mixed_add") (param $x f64) (param $y f32) (result f32)
   656      (f32.demote_f64 (f64.add (local.get $x) (f64.promote_f32 (local.get $y)))))
   657    (func (export "no_demote_mixed_add_commuted") (param $y f32) (param $x f64) (result f32)
   658      (f32.demote_f64 (f64.add (f64.promote_f32 (local.get $y)) (local.get $x))))
   659  )
   660  
   661  (assert_return (invoke "no_demote_mixed_add" (f64.const 0x1.f51a9d04854f9p-95) (f32.const 0x1.3f4e9cp-119)) (f32.const 0x1.f51a9ep-95))
   662  (assert_return (invoke "no_demote_mixed_add" (f64.const 0x1.065b3d81ad8dp+37) (f32.const 0x1.758cd8p+38)) (f32.const 0x1.f8ba76p+38))
   663  (assert_return (invoke "no_demote_mixed_add" (f64.const 0x1.626c80963bd17p-119) (f32.const -0x1.9bbf86p-121)) (f32.const 0x1.f6f93ep-120))
   664  (assert_return (invoke "no_demote_mixed_add" (f64.const -0x1.0d5110e3385bbp-20) (f32.const 0x1.096f4ap-29)) (f32.const -0x1.0ccc5ap-20))
   665  (assert_return (invoke "no_demote_mixed_add" (f64.const -0x1.73852db4e5075p-20) (f32.const -0x1.24e474p-41)) (f32.const -0x1.738536p-20))
   666  
   667  (assert_return (invoke "no_demote_mixed_add_commuted" (f32.const 0x1.3f4e9cp-119) (f64.const 0x1.f51a9d04854f9p-95)) (f32.const 0x1.f51a9ep-95))
   668  (assert_return (invoke "no_demote_mixed_add_commuted" (f32.const 0x1.758cd8p+38) (f64.const 0x1.065b3d81ad8dp+37)) (f32.const 0x1.f8ba76p+38))
   669  (assert_return (invoke "no_demote_mixed_add_commuted" (f32.const -0x1.9bbf86p-121) (f64.const 0x1.626c80963bd17p-119)) (f32.const 0x1.f6f93ep-120))
   670  (assert_return (invoke "no_demote_mixed_add_commuted" (f32.const 0x1.096f4ap-29) (f64.const -0x1.0d5110e3385bbp-20)) (f32.const -0x1.0ccc5ap-20))
   671  (assert_return (invoke "no_demote_mixed_add_commuted" (f32.const -0x1.24e474p-41) (f64.const -0x1.73852db4e5075p-20)) (f32.const -0x1.738536p-20))
   672  
   673  ;; Test that demote(x-promote(y)) is not folded to demote(x)-y.
   674  
   675  (module
   676    (func (export "no_demote_mixed_sub") (param $x f64) (param $y f32) (result f32)
   677      (f32.demote_f64 (f64.sub (local.get $x) (f64.promote_f32 (local.get $y)))))
   678  )
   679  
   680  (assert_return (invoke "no_demote_mixed_sub" (f64.const 0x1.a0a183220e9b1p+82) (f32.const 0x1.c5acf8p+61)) (f32.const 0x1.a0a174p+82))
   681  (assert_return (invoke "no_demote_mixed_sub" (f64.const -0x1.6e2c5ac39f63ep+30) (f32.const 0x1.d48ca4p+17)) (f32.const -0x1.6e3bp+30))
   682  (assert_return (invoke "no_demote_mixed_sub" (f64.const -0x1.98c74350dde6ap+6) (f32.const 0x1.9d69bcp-12)) (f32.const -0x1.98c7aap+6))
   683  (assert_return (invoke "no_demote_mixed_sub" (f64.const 0x1.0459f34091dbfp-54) (f32.const 0x1.61ad08p-71)) (f32.const 0x1.045942p-54))
   684  (assert_return (invoke "no_demote_mixed_sub" (f64.const 0x1.a7498dca3fdb7p+14) (f32.const 0x1.ed21c8p+15)) (f32.const -0x1.197d02p+15))
   685  
   686  ;; Test that converting between integer and float and back isn't folded away.
   687  
   688  (module
   689    (func (export "f32.i32.no_fold_trunc_s_convert_s") (param $x f32) (result f32)
   690      (f32.convert_i32_s (i32.trunc_f32_s (local.get $x))))
   691    (func (export "f32.i32.no_fold_trunc_u_convert_s") (param $x f32) (result f32)
   692      (f32.convert_i32_s (i32.trunc_f32_u (local.get $x))))
   693    (func (export "f32.i32.no_fold_trunc_s_convert_u") (param $x f32) (result f32)
   694      (f32.convert_i32_u (i32.trunc_f32_s (local.get $x))))
   695    (func (export "f32.i32.no_fold_trunc_u_convert_u") (param $x f32) (result f32)
   696      (f32.convert_i32_u (i32.trunc_f32_u (local.get $x))))
   697    (func (export "f64.i32.no_fold_trunc_s_convert_s") (param $x f64) (result f64)
   698      (f64.convert_i32_s (i32.trunc_f64_s (local.get $x))))
   699    (func (export "f64.i32.no_fold_trunc_u_convert_s") (param $x f64) (result f64)
   700      (f64.convert_i32_s (i32.trunc_f64_u (local.get $x))))
   701    (func (export "f64.i32.no_fold_trunc_s_convert_u") (param $x f64) (result f64)
   702      (f64.convert_i32_u (i32.trunc_f64_s (local.get $x))))
   703    (func (export "f64.i32.no_fold_trunc_u_convert_u") (param $x f64) (result f64)
   704      (f64.convert_i32_u (i32.trunc_f64_u (local.get $x))))
   705    (func (export "f32.i64.no_fold_trunc_s_convert_s") (param $x f32) (result f32)
   706      (f32.convert_i64_s (i64.trunc_f32_s (local.get $x))))
   707    (func (export "f32.i64.no_fold_trunc_u_convert_s") (param $x f32) (result f32)
   708      (f32.convert_i64_s (i64.trunc_f32_u (local.get $x))))
   709    (func (export "f32.i64.no_fold_trunc_s_convert_u") (param $x f32) (result f32)
   710      (f32.convert_i64_u (i64.trunc_f32_s (local.get $x))))
   711    (func (export "f32.i64.no_fold_trunc_u_convert_u") (param $x f32) (result f32)
   712      (f32.convert_i64_u (i64.trunc_f32_u (local.get $x))))
   713    (func (export "f64.i64.no_fold_trunc_s_convert_s") (param $x f64) (result f64)
   714      (f64.convert_i64_s (i64.trunc_f64_s (local.get $x))))
   715    (func (export "f64.i64.no_fold_trunc_u_convert_s") (param $x f64) (result f64)
   716      (f64.convert_i64_s (i64.trunc_f64_u (local.get $x))))
   717    (func (export "f64.i64.no_fold_trunc_s_convert_u") (param $x f64) (result f64)
   718      (f64.convert_i64_u (i64.trunc_f64_s (local.get $x))))
   719    (func (export "f64.i64.no_fold_trunc_u_convert_u") (param $x f64) (result f64)
   720      (f64.convert_i64_u (i64.trunc_f64_u (local.get $x))))
   721  )
   722  
   723  (assert_return (invoke "f32.i32.no_fold_trunc_s_convert_s" (f32.const 1.5)) (f32.const 1.0))
   724  (assert_return (invoke "f32.i32.no_fold_trunc_s_convert_s" (f32.const -1.5)) (f32.const -1.0))
   725  (assert_return (invoke "f32.i32.no_fold_trunc_u_convert_s" (f32.const 1.5)) (f32.const 1.0))
   726  (assert_return (invoke "f32.i32.no_fold_trunc_u_convert_s" (f32.const -0.5)) (f32.const 0.0))
   727  (assert_return (invoke "f32.i32.no_fold_trunc_s_convert_u" (f32.const 1.5)) (f32.const 1.0))
   728  (assert_return (invoke "f32.i32.no_fold_trunc_s_convert_u" (f32.const -1.5)) (f32.const 0x1p+32))
   729  (assert_return (invoke "f32.i32.no_fold_trunc_u_convert_u" (f32.const 1.5)) (f32.const 1.0))
   730  (assert_return (invoke "f32.i32.no_fold_trunc_u_convert_u" (f32.const -0.5)) (f32.const 0.0))
   731  
   732  (assert_return (invoke "f64.i32.no_fold_trunc_s_convert_s" (f64.const 1.5)) (f64.const 1.0))
   733  (assert_return (invoke "f64.i32.no_fold_trunc_s_convert_s" (f64.const -1.5)) (f64.const -1.0))
   734  (assert_return (invoke "f64.i32.no_fold_trunc_u_convert_s" (f64.const 1.5)) (f64.const 1.0))
   735  (assert_return (invoke "f64.i32.no_fold_trunc_u_convert_s" (f64.const -0.5)) (f64.const 0.0))
   736  (assert_return (invoke "f64.i32.no_fold_trunc_s_convert_u" (f64.const 1.5)) (f64.const 1.0))
   737  (assert_return (invoke "f64.i32.no_fold_trunc_s_convert_u" (f64.const -1.5)) (f64.const 0x1.fffffffep+31))
   738  (assert_return (invoke "f64.i32.no_fold_trunc_u_convert_u" (f64.const 1.5)) (f64.const 1.0))
   739  (assert_return (invoke "f64.i32.no_fold_trunc_u_convert_u" (f64.const -0.5)) (f64.const 0.0))
   740  
   741  (assert_return (invoke "f32.i64.no_fold_trunc_s_convert_s" (f32.const 1.5)) (f32.const 1.0))
   742  (assert_return (invoke "f32.i64.no_fold_trunc_s_convert_s" (f32.const -1.5)) (f32.const -1.0))
   743  (assert_return (invoke "f32.i64.no_fold_trunc_u_convert_s" (f32.const 1.5)) (f32.const 1.0))
   744  (assert_return (invoke "f32.i64.no_fold_trunc_u_convert_s" (f32.const -0.5)) (f32.const 0.0))
   745  (assert_return (invoke "f32.i64.no_fold_trunc_s_convert_u" (f32.const 1.5)) (f32.const 1.0))
   746  (assert_return (invoke "f32.i64.no_fold_trunc_s_convert_u" (f32.const -1.5)) (f32.const 0x1p+64))
   747  (assert_return (invoke "f32.i64.no_fold_trunc_u_convert_u" (f32.const 1.5)) (f32.const 1.0))
   748  (assert_return (invoke "f32.i64.no_fold_trunc_u_convert_u" (f32.const -0.5)) (f32.const 0.0))
   749  
   750  (assert_return (invoke "f64.i64.no_fold_trunc_s_convert_s" (f64.const 1.5)) (f64.const 1.0))
   751  (assert_return (invoke "f64.i64.no_fold_trunc_s_convert_s" (f64.const -1.5)) (f64.const -1.0))
   752  (assert_return (invoke "f64.i64.no_fold_trunc_u_convert_s" (f64.const 1.5)) (f64.const 1.0))
   753  (assert_return (invoke "f64.i64.no_fold_trunc_u_convert_s" (f64.const -0.5)) (f64.const 0.0))
   754  (assert_return (invoke "f64.i64.no_fold_trunc_s_convert_u" (f64.const 1.5)) (f64.const 1.0))
   755  (assert_return (invoke "f64.i64.no_fold_trunc_s_convert_u" (f64.const -1.5)) (f64.const 0x1p+64))
   756  (assert_return (invoke "f64.i64.no_fold_trunc_u_convert_u" (f64.const 1.5)) (f64.const 1.0))
   757  (assert_return (invoke "f64.i64.no_fold_trunc_u_convert_u" (f64.const -0.5)) (f64.const 0.0))
   758  
   759  ;; Test that dividing by a loop-invariant constant isn't optimized to be a
   760  ;; multiplication by a reciprocal, which would be particularly tempting since
   761  ;; the reciprocal computation could be hoisted.
   762  
   763  (module
   764    (memory 1 1)
   765    (func (export "init") (param $i i32) (param $x f32) (f32.store (local.get $i) (local.get $x)))
   766  
   767    (func (export "run") (param $n i32) (param $z f32)
   768      (local $i i32)
   769      (block $exit
   770        (loop $cont
   771          (f32.store
   772            (local.get $i)
   773            (f32.div (f32.load (local.get $i)) (local.get $z))
   774          )
   775          (local.set $i (i32.add (local.get $i) (i32.const 4)))
   776          (br_if $cont (i32.lt_u (local.get $i) (local.get $n)))
   777        )
   778      )
   779    )
   780  
   781    (func (export "check") (param $i i32) (result f32) (f32.load (local.get $i)))
   782  )
   783  
   784  (invoke "init" (i32.const  0) (f32.const 15.1))
   785  (invoke "init" (i32.const  4) (f32.const 15.2))
   786  (invoke "init" (i32.const  8) (f32.const 15.3))
   787  (invoke "init" (i32.const 12) (f32.const 15.4))
   788  (assert_return (invoke "check" (i32.const  0)) (f32.const 15.1))
   789  (assert_return (invoke "check" (i32.const  4)) (f32.const 15.2))
   790  (assert_return (invoke "check" (i32.const  8)) (f32.const 15.3))
   791  (assert_return (invoke "check" (i32.const 12)) (f32.const 15.4))
   792  (invoke "run" (i32.const 16) (f32.const 3.0))
   793  (assert_return (invoke "check" (i32.const  0)) (f32.const 0x1.422222p+2))
   794  (assert_return (invoke "check" (i32.const  4)) (f32.const 0x1.444444p+2))
   795  (assert_return (invoke "check" (i32.const  8)) (f32.const 0x1.466666p+2))
   796  (assert_return (invoke "check" (i32.const 12)) (f32.const 0x1.488888p+2))
   797  
   798  (module
   799    (memory 1 1)
   800    (func (export "init") (param $i i32) (param $x f64) (f64.store (local.get $i) (local.get $x)))
   801  
   802    (func (export "run") (param $n i32) (param $z f64)
   803      (local $i i32)
   804      (block $exit
   805        (loop $cont
   806          (f64.store
   807            (local.get $i)
   808            (f64.div (f64.load (local.get $i)) (local.get $z))
   809          )
   810          (local.set $i (i32.add (local.get $i) (i32.const 8)))
   811          (br_if $cont (i32.lt_u (local.get $i) (local.get $n)))
   812        )
   813      )
   814    )
   815  
   816    (func (export "check") (param $i i32) (result f64) (f64.load (local.get $i)))
   817  )
   818  
   819  (invoke "init" (i32.const  0) (f64.const 15.1))
   820  (invoke "init" (i32.const  8) (f64.const 15.2))
   821  (invoke "init" (i32.const 16) (f64.const 15.3))
   822  (invoke "init" (i32.const 24) (f64.const 15.4))
   823  (assert_return (invoke "check" (i32.const  0)) (f64.const 15.1))
   824  (assert_return (invoke "check" (i32.const  8)) (f64.const 15.2))
   825  (assert_return (invoke "check" (i32.const 16)) (f64.const 15.3))
   826  (assert_return (invoke "check" (i32.const 24)) (f64.const 15.4))
   827  (invoke "run" (i32.const 32) (f64.const 3.0))
   828  (assert_return (invoke "check" (i32.const 0)) (f64.const 0x1.4222222222222p+2))
   829  (assert_return (invoke "check" (i32.const 8)) (f64.const 0x1.4444444444444p+2))
   830  (assert_return (invoke "check" (i32.const 16)) (f64.const 0x1.4666666666667p+2))
   831  (assert_return (invoke "check" (i32.const 24)) (f64.const 0x1.4888888888889p+2))
   832  
   833  ;; Test that ult/ugt/etc. aren't folded to olt/ogt/etc.
   834  
   835  (module
   836    (func (export "f32.ult") (param $x f32) (param $y f32) (result i32) (i32.eqz (f32.ge (local.get $x) (local.get $y))))
   837    (func (export "f32.ule") (param $x f32) (param $y f32) (result i32) (i32.eqz (f32.gt (local.get $x) (local.get $y))))
   838    (func (export "f32.ugt") (param $x f32) (param $y f32) (result i32) (i32.eqz (f32.le (local.get $x) (local.get $y))))
   839    (func (export "f32.uge") (param $x f32) (param $y f32) (result i32) (i32.eqz (f32.lt (local.get $x) (local.get $y))))
   840  
   841    (func (export "f64.ult") (param $x f64) (param $y f64) (result i32) (i32.eqz (f64.ge (local.get $x) (local.get $y))))
   842    (func (export "f64.ule") (param $x f64) (param $y f64) (result i32) (i32.eqz (f64.gt (local.get $x) (local.get $y))))
   843    (func (export "f64.ugt") (param $x f64) (param $y f64) (result i32) (i32.eqz (f64.le (local.get $x) (local.get $y))))
   844    (func (export "f64.uge") (param $x f64) (param $y f64) (result i32) (i32.eqz (f64.lt (local.get $x) (local.get $y))))
   845  )
   846  
   847  (assert_return (invoke "f32.ult" (f32.const 3.0) (f32.const 2.0)) (i32.const 0))
   848  (assert_return (invoke "f32.ult" (f32.const 2.0) (f32.const 2.0)) (i32.const 0))
   849  (assert_return (invoke "f32.ult" (f32.const 2.0) (f32.const 3.0)) (i32.const 1))
   850  (assert_return (invoke "f32.ult" (f32.const 2.0) (f32.const nan)) (i32.const 1))
   851  (assert_return (invoke "f32.ule" (f32.const 3.0) (f32.const 2.0)) (i32.const 0))
   852  (assert_return (invoke "f32.ule" (f32.const 2.0) (f32.const 2.0)) (i32.const 1))
   853  (assert_return (invoke "f32.ule" (f32.const 2.0) (f32.const 3.0)) (i32.const 1))
   854  (assert_return (invoke "f32.ule" (f32.const 2.0) (f32.const nan)) (i32.const 1))
   855  (assert_return (invoke "f32.ugt" (f32.const 3.0) (f32.const 2.0)) (i32.const 1))
   856  (assert_return (invoke "f32.ugt" (f32.const 2.0) (f32.const 2.0)) (i32.const 0))
   857  (assert_return (invoke "f32.ugt" (f32.const 2.0) (f32.const 3.0)) (i32.const 0))
   858  (assert_return (invoke "f32.ugt" (f32.const 2.0) (f32.const nan)) (i32.const 1))
   859  (assert_return (invoke "f32.uge" (f32.const 3.0) (f32.const 2.0)) (i32.const 1))
   860  (assert_return (invoke "f32.uge" (f32.const 2.0) (f32.const 2.0)) (i32.const 1))
   861  (assert_return (invoke "f32.uge" (f32.const 2.0) (f32.const 3.0)) (i32.const 0))
   862  (assert_return (invoke "f32.uge" (f32.const 2.0) (f32.const nan)) (i32.const 1))
   863  (assert_return (invoke "f64.ult" (f64.const 3.0) (f64.const 2.0)) (i32.const 0))
   864  (assert_return (invoke "f64.ult" (f64.const 2.0) (f64.const 2.0)) (i32.const 0))
   865  (assert_return (invoke "f64.ult" (f64.const 2.0) (f64.const 3.0)) (i32.const 1))
   866  (assert_return (invoke "f64.ult" (f64.const 2.0) (f64.const nan)) (i32.const 1))
   867  (assert_return (invoke "f64.ule" (f64.const 3.0) (f64.const 2.0)) (i32.const 0))
   868  (assert_return (invoke "f64.ule" (f64.const 2.0) (f64.const 2.0)) (i32.const 1))
   869  (assert_return (invoke "f64.ule" (f64.const 2.0) (f64.const 3.0)) (i32.const 1))
   870  (assert_return (invoke "f64.ule" (f64.const 2.0) (f64.const nan)) (i32.const 1))
   871  (assert_return (invoke "f64.ugt" (f64.const 3.0) (f64.const 2.0)) (i32.const 1))
   872  (assert_return (invoke "f64.ugt" (f64.const 2.0) (f64.const 2.0)) (i32.const 0))
   873  (assert_return (invoke "f64.ugt" (f64.const 2.0) (f64.const 3.0)) (i32.const 0))
   874  (assert_return (invoke "f64.ugt" (f64.const 2.0) (f64.const nan)) (i32.const 1))
   875  (assert_return (invoke "f64.uge" (f64.const 3.0) (f64.const 2.0)) (i32.const 1))
   876  (assert_return (invoke "f64.uge" (f64.const 2.0) (f64.const 2.0)) (i32.const 1))
   877  (assert_return (invoke "f64.uge" (f64.const 2.0) (f64.const 3.0)) (i32.const 0))
   878  (assert_return (invoke "f64.uge" (f64.const 2.0) (f64.const nan)) (i32.const 1))
   879  
   880  ;; Test that x<y?x:y, etc. using select aren't folded to min, etc.
   881  
   882  (module
   883    (func (export "f32.no_fold_lt_select") (param $x f32) (param $y f32) (result f32) (select (local.get $x) (local.get $y) (f32.lt (local.get $x) (local.get $y))))
   884    (func (export "f32.no_fold_le_select") (param $x f32) (param $y f32) (result f32) (select (local.get $x) (local.get $y) (f32.le (local.get $x) (local.get $y))))
   885    (func (export "f32.no_fold_gt_select") (param $x f32) (param $y f32) (result f32) (select (local.get $x) (local.get $y) (f32.gt (local.get $x) (local.get $y))))
   886    (func (export "f32.no_fold_ge_select") (param $x f32) (param $y f32) (result f32) (select (local.get $x) (local.get $y) (f32.ge (local.get $x) (local.get $y))))
   887  
   888    (func (export "f64.no_fold_lt_select") (param $x f64) (param $y f64) (result f64) (select (local.get $x) (local.get $y) (f64.lt (local.get $x) (local.get $y))))
   889    (func (export "f64.no_fold_le_select") (param $x f64) (param $y f64) (result f64) (select (local.get $x) (local.get $y) (f64.le (local.get $x) (local.get $y))))
   890    (func (export "f64.no_fold_gt_select") (param $x f64) (param $y f64) (result f64) (select (local.get $x) (local.get $y) (f64.gt (local.get $x) (local.get $y))))
   891    (func (export "f64.no_fold_ge_select") (param $x f64) (param $y f64) (result f64) (select (local.get $x) (local.get $y) (f64.ge (local.get $x) (local.get $y))))
   892  )
   893  
   894  (assert_return (invoke "f32.no_fold_lt_select" (f32.const 0.0) (f32.const nan)) (f32.const nan))
   895  (assert_return (invoke "f32.no_fold_lt_select" (f32.const nan) (f32.const 0.0)) (f32.const 0.0))
   896  (assert_return (invoke "f32.no_fold_lt_select" (f32.const 0.0) (f32.const -0.0)) (f32.const -0.0))
   897  (assert_return (invoke "f32.no_fold_lt_select" (f32.const -0.0) (f32.const 0.0)) (f32.const 0.0))
   898  (assert_return (invoke "f32.no_fold_le_select" (f32.const 0.0) (f32.const nan)) (f32.const nan))
   899  (assert_return (invoke "f32.no_fold_le_select" (f32.const nan) (f32.const 0.0)) (f32.const 0.0))
   900  (assert_return (invoke "f32.no_fold_le_select" (f32.const 0.0) (f32.const -0.0)) (f32.const 0.0))
   901  (assert_return (invoke "f32.no_fold_le_select" (f32.const -0.0) (f32.const 0.0)) (f32.const -0.0))
   902  (assert_return (invoke "f32.no_fold_gt_select" (f32.const 0.0) (f32.const nan)) (f32.const nan))
   903  (assert_return (invoke "f32.no_fold_gt_select" (f32.const nan) (f32.const 0.0)) (f32.const 0.0))
   904  (assert_return (invoke "f32.no_fold_gt_select" (f32.const 0.0) (f32.const -0.0)) (f32.const -0.0))
   905  (assert_return (invoke "f32.no_fold_gt_select" (f32.const -0.0) (f32.const 0.0)) (f32.const 0.0))
   906  (assert_return (invoke "f32.no_fold_ge_select" (f32.const 0.0) (f32.const nan)) (f32.const nan))
   907  (assert_return (invoke "f32.no_fold_ge_select" (f32.const nan) (f32.const 0.0)) (f32.const 0.0))
   908  (assert_return (invoke "f32.no_fold_ge_select" (f32.const 0.0) (f32.const -0.0)) (f32.const 0.0))
   909  (assert_return (invoke "f32.no_fold_ge_select" (f32.const -0.0) (f32.const 0.0)) (f32.const -0.0))
   910  (assert_return (invoke "f64.no_fold_lt_select" (f64.const 0.0) (f64.const nan)) (f64.const nan))
   911  (assert_return (invoke "f64.no_fold_lt_select" (f64.const nan) (f64.const 0.0)) (f64.const 0.0))
   912  (assert_return (invoke "f64.no_fold_lt_select" (f64.const 0.0) (f64.const -0.0)) (f64.const -0.0))
   913  (assert_return (invoke "f64.no_fold_lt_select" (f64.const -0.0) (f64.const 0.0)) (f64.const 0.0))
   914  (assert_return (invoke "f64.no_fold_le_select" (f64.const 0.0) (f64.const nan)) (f64.const nan))
   915  (assert_return (invoke "f64.no_fold_le_select" (f64.const nan) (f64.const 0.0)) (f64.const 0.0))
   916  (assert_return (invoke "f64.no_fold_le_select" (f64.const 0.0) (f64.const -0.0)) (f64.const 0.0))
   917  (assert_return (invoke "f64.no_fold_le_select" (f64.const -0.0) (f64.const 0.0)) (f64.const -0.0))
   918  (assert_return (invoke "f64.no_fold_gt_select" (f64.const 0.0) (f64.const nan)) (f64.const nan))
   919  (assert_return (invoke "f64.no_fold_gt_select" (f64.const nan) (f64.const 0.0)) (f64.const 0.0))
   920  (assert_return (invoke "f64.no_fold_gt_select" (f64.const 0.0) (f64.const -0.0)) (f64.const -0.0))
   921  (assert_return (invoke "f64.no_fold_gt_select" (f64.const -0.0) (f64.const 0.0)) (f64.const 0.0))
   922  (assert_return (invoke "f64.no_fold_ge_select" (f64.const 0.0) (f64.const nan)) (f64.const nan))
   923  (assert_return (invoke "f64.no_fold_ge_select" (f64.const nan) (f64.const 0.0)) (f64.const 0.0))
   924  (assert_return (invoke "f64.no_fold_ge_select" (f64.const 0.0) (f64.const -0.0)) (f64.const 0.0))
   925  (assert_return (invoke "f64.no_fold_ge_select" (f64.const -0.0) (f64.const 0.0)) (f64.const -0.0))
   926  
   927  ;; Test that x<y?x:y, etc. using if and else aren't folded to min, etc.
   928  
   929  (module
   930    (func (export "f32.no_fold_lt_if") (param $x f32) (param $y f32) (result f32)
   931      (if (result f32) (f32.lt (local.get $x) (local.get $y))
   932        (then (local.get $x)) (else (local.get $y))
   933      )
   934    )
   935    (func (export "f32.no_fold_le_if") (param $x f32) (param $y f32) (result f32)
   936      (if (result f32) (f32.le (local.get $x) (local.get $y))
   937        (then (local.get $x)) (else (local.get $y))
   938      )
   939    )
   940    (func (export "f32.no_fold_gt_if") (param $x f32) (param $y f32) (result f32)
   941      (if (result f32) (f32.gt (local.get $x) (local.get $y))
   942        (then (local.get $x)) (else (local.get $y))
   943      )
   944    )
   945    (func (export "f32.no_fold_ge_if") (param $x f32) (param $y f32) (result f32)
   946      (if (result f32) (f32.ge (local.get $x) (local.get $y))
   947        (then (local.get $x)) (else (local.get $y))
   948      )
   949    )
   950  
   951    (func (export "f64.no_fold_lt_if") (param $x f64) (param $y f64) (result f64)
   952      (if (result f64) (f64.lt (local.get $x) (local.get $y))
   953        (then (local.get $x)) (else (local.get $y))
   954      )
   955    )
   956    (func (export "f64.no_fold_le_if") (param $x f64) (param $y f64) (result f64)
   957      (if (result f64) (f64.le (local.get $x) (local.get $y))
   958        (then (local.get $x)) (else (local.get $y))
   959      )
   960    )
   961    (func (export "f64.no_fold_gt_if") (param $x f64) (param $y f64) (result f64)
   962      (if (result f64) (f64.gt (local.get $x) (local.get $y))
   963        (then (local.get $x)) (else (local.get $y))
   964      )
   965    )
   966    (func (export "f64.no_fold_ge_if") (param $x f64) (param $y f64) (result f64)
   967      (if (result f64) (f64.ge (local.get $x) (local.get $y))
   968        (then (local.get $x)) (else (local.get $y))
   969      )
   970    )
   971  )
   972  
   973  (assert_return (invoke "f32.no_fold_lt_if" (f32.const 0.0) (f32.const nan)) (f32.const nan))
   974  (assert_return (invoke "f32.no_fold_lt_if" (f32.const nan) (f32.const 0.0)) (f32.const 0.0))
   975  (assert_return (invoke "f32.no_fold_lt_if" (f32.const 0.0) (f32.const -0.0)) (f32.const -0.0))
   976  (assert_return (invoke "f32.no_fold_lt_if" (f32.const -0.0) (f32.const 0.0)) (f32.const 0.0))
   977  (assert_return (invoke "f32.no_fold_le_if" (f32.const 0.0) (f32.const nan)) (f32.const nan))
   978  (assert_return (invoke "f32.no_fold_le_if" (f32.const nan) (f32.const 0.0)) (f32.const 0.0))
   979  (assert_return (invoke "f32.no_fold_le_if" (f32.const 0.0) (f32.const -0.0)) (f32.const 0.0))
   980  (assert_return (invoke "f32.no_fold_le_if" (f32.const -0.0) (f32.const 0.0)) (f32.const -0.0))
   981  (assert_return (invoke "f32.no_fold_gt_if" (f32.const 0.0) (f32.const nan)) (f32.const nan))
   982  (assert_return (invoke "f32.no_fold_gt_if" (f32.const nan) (f32.const 0.0)) (f32.const 0.0))
   983  (assert_return (invoke "f32.no_fold_gt_if" (f32.const 0.0) (f32.const -0.0)) (f32.const -0.0))
   984  (assert_return (invoke "f32.no_fold_gt_if" (f32.const -0.0) (f32.const 0.0)) (f32.const 0.0))
   985  (assert_return (invoke "f32.no_fold_ge_if" (f32.const 0.0) (f32.const nan)) (f32.const nan))
   986  (assert_return (invoke "f32.no_fold_ge_if" (f32.const nan) (f32.const 0.0)) (f32.const 0.0))
   987  (assert_return (invoke "f32.no_fold_ge_if" (f32.const 0.0) (f32.const -0.0)) (f32.const 0.0))
   988  (assert_return (invoke "f32.no_fold_ge_if" (f32.const -0.0) (f32.const 0.0)) (f32.const -0.0))
   989  (assert_return (invoke "f64.no_fold_lt_if" (f64.const 0.0) (f64.const nan)) (f64.const nan))
   990  (assert_return (invoke "f64.no_fold_lt_if" (f64.const nan) (f64.const 0.0)) (f64.const 0.0))
   991  (assert_return (invoke "f64.no_fold_lt_if" (f64.const 0.0) (f64.const -0.0)) (f64.const -0.0))
   992  (assert_return (invoke "f64.no_fold_lt_if" (f64.const -0.0) (f64.const 0.0)) (f64.const 0.0))
   993  (assert_return (invoke "f64.no_fold_le_if" (f64.const 0.0) (f64.const nan)) (f64.const nan))
   994  (assert_return (invoke "f64.no_fold_le_if" (f64.const nan) (f64.const 0.0)) (f64.const 0.0))
   995  (assert_return (invoke "f64.no_fold_le_if" (f64.const 0.0) (f64.const -0.0)) (f64.const 0.0))
   996  (assert_return (invoke "f64.no_fold_le_if" (f64.const -0.0) (f64.const 0.0)) (f64.const -0.0))
   997  (assert_return (invoke "f64.no_fold_gt_if" (f64.const 0.0) (f64.const nan)) (f64.const nan))
   998  (assert_return (invoke "f64.no_fold_gt_if" (f64.const nan) (f64.const 0.0)) (f64.const 0.0))
   999  (assert_return (invoke "f64.no_fold_gt_if" (f64.const 0.0) (f64.const -0.0)) (f64.const -0.0))
  1000  (assert_return (invoke "f64.no_fold_gt_if" (f64.const -0.0) (f64.const 0.0)) (f64.const 0.0))
  1001  (assert_return (invoke "f64.no_fold_ge_if" (f64.const 0.0) (f64.const nan)) (f64.const nan))
  1002  (assert_return (invoke "f64.no_fold_ge_if" (f64.const nan) (f64.const 0.0)) (f64.const 0.0))
  1003  (assert_return (invoke "f64.no_fold_ge_if" (f64.const 0.0) (f64.const -0.0)) (f64.const 0.0))
  1004  (assert_return (invoke "f64.no_fold_ge_if" (f64.const -0.0) (f64.const 0.0)) (f64.const -0.0))
  1005  
  1006  ;; Test that x<0?-x:x, etc. using select aren't folded to abs.
  1007  
  1008  (module
  1009    (func (export "f32.no_fold_lt_select_to_abs") (param $x f32) (result f32) (select (f32.neg (local.get $x)) (local.get $x) (f32.lt (local.get $x) (f32.const 0.0))))
  1010    (func (export "f32.no_fold_le_select_to_abs") (param $x f32) (result f32) (select (f32.neg (local.get $x)) (local.get $x) (f32.le (local.get $x) (f32.const -0.0))))
  1011    (func (export "f32.no_fold_gt_select_to_abs") (param $x f32) (result f32) (select (local.get $x) (f32.neg (local.get $x)) (f32.gt (local.get $x) (f32.const -0.0))))
  1012    (func (export "f32.no_fold_ge_select_to_abs") (param $x f32) (result f32) (select (local.get $x) (f32.neg (local.get $x)) (f32.ge (local.get $x) (f32.const 0.0))))
  1013  
  1014    (func (export "f64.no_fold_lt_select_to_abs") (param $x f64) (result f64) (select (f64.neg (local.get $x)) (local.get $x) (f64.lt (local.get $x) (f64.const 0.0))))
  1015    (func (export "f64.no_fold_le_select_to_abs") (param $x f64) (result f64) (select (f64.neg (local.get $x)) (local.get $x) (f64.le (local.get $x) (f64.const -0.0))))
  1016    (func (export "f64.no_fold_gt_select_to_abs") (param $x f64) (result f64) (select (local.get $x) (f64.neg (local.get $x)) (f64.gt (local.get $x) (f64.const -0.0))))
  1017    (func (export "f64.no_fold_ge_select_to_abs") (param $x f64) (result f64) (select (local.get $x) (f64.neg (local.get $x)) (f64.ge (local.get $x) (f64.const 0.0))))
  1018  )
  1019  
  1020  (assert_return (invoke "f32.no_fold_lt_select_to_abs" (f32.const nan:0x200000)) (f32.const nan:0x200000))
  1021  (assert_return (invoke "f32.no_fold_lt_select_to_abs" (f32.const -nan)) (f32.const -nan))
  1022  (assert_return (invoke "f32.no_fold_lt_select_to_abs" (f32.const 0.0)) (f32.const 0.0))
  1023  (assert_return (invoke "f32.no_fold_lt_select_to_abs" (f32.const -0.0)) (f32.const -0.0))
  1024  (assert_return (invoke "f32.no_fold_le_select_to_abs" (f32.const nan:0x200000)) (f32.const nan:0x200000))
  1025  (assert_return (invoke "f32.no_fold_le_select_to_abs" (f32.const -nan)) (f32.const -nan))
  1026  (assert_return (invoke "f32.no_fold_le_select_to_abs" (f32.const 0.0)) (f32.const -0.0))
  1027  (assert_return (invoke "f32.no_fold_le_select_to_abs" (f32.const -0.0)) (f32.const 0.0))
  1028  (assert_return (invoke "f32.no_fold_gt_select_to_abs" (f32.const nan:0x200000)) (f32.const -nan:0x200000))
  1029  (assert_return (invoke "f32.no_fold_gt_select_to_abs" (f32.const -nan)) (f32.const nan))
  1030  (assert_return (invoke "f32.no_fold_gt_select_to_abs" (f32.const 0.0)) (f32.const -0.0))
  1031  (assert_return (invoke "f32.no_fold_gt_select_to_abs" (f32.const -0.0)) (f32.const 0.0))
  1032  (assert_return (invoke "f32.no_fold_ge_select_to_abs" (f32.const nan:0x200000)) (f32.const -nan:0x200000))
  1033  (assert_return (invoke "f32.no_fold_ge_select_to_abs" (f32.const -nan)) (f32.const nan))
  1034  (assert_return (invoke "f32.no_fold_ge_select_to_abs" (f32.const 0.0)) (f32.const 0.0))
  1035  (assert_return (invoke "f32.no_fold_ge_select_to_abs" (f32.const -0.0)) (f32.const -0.0))
  1036  (assert_return (invoke "f64.no_fold_lt_select_to_abs" (f64.const nan:0x4000000000000)) (f64.const nan:0x4000000000000))
  1037  (assert_return (invoke "f64.no_fold_lt_select_to_abs" (f64.const -nan)) (f64.const -nan))
  1038  (assert_return (invoke "f64.no_fold_lt_select_to_abs" (f64.const 0.0)) (f64.const 0.0))
  1039  (assert_return (invoke "f64.no_fold_lt_select_to_abs" (f64.const -0.0)) (f64.const -0.0))
  1040  (assert_return (invoke "f64.no_fold_le_select_to_abs" (f64.const nan:0x4000000000000)) (f64.const nan:0x4000000000000))
  1041  (assert_return (invoke "f64.no_fold_le_select_to_abs" (f64.const -nan)) (f64.const -nan))
  1042  (assert_return (invoke "f64.no_fold_le_select_to_abs" (f64.const 0.0)) (f64.const -0.0))
  1043  (assert_return (invoke "f64.no_fold_le_select_to_abs" (f64.const -0.0)) (f64.const 0.0))
  1044  (assert_return (invoke "f64.no_fold_gt_select_to_abs" (f64.const nan:0x4000000000000)) (f64.const -nan:0x4000000000000))
  1045  (assert_return (invoke "f64.no_fold_gt_select_to_abs" (f64.const -nan)) (f64.const nan))
  1046  (assert_return (invoke "f64.no_fold_gt_select_to_abs" (f64.const 0.0)) (f64.const -0.0))
  1047  (assert_return (invoke "f64.no_fold_gt_select_to_abs" (f64.const -0.0)) (f64.const 0.0))
  1048  (assert_return (invoke "f64.no_fold_ge_select_to_abs" (f64.const nan:0x4000000000000)) (f64.const -nan:0x4000000000000))
  1049  (assert_return (invoke "f64.no_fold_ge_select_to_abs" (f64.const -nan)) (f64.const nan))
  1050  (assert_return (invoke "f64.no_fold_ge_select_to_abs" (f64.const 0.0)) (f64.const 0.0))
  1051  (assert_return (invoke "f64.no_fold_ge_select_to_abs" (f64.const -0.0)) (f64.const -0.0))
  1052  
  1053  ;; Test that x<0?-x:x, etc. using if aren't folded to abs.
  1054  
  1055  (module
  1056    (func (export "f32.no_fold_lt_if_to_abs") (param $x f32) (result f32)
  1057      (if (result f32) (f32.lt (local.get $x) (f32.const 0.0))
  1058        (then (f32.neg (local.get $x))) (else (local.get $x))
  1059      )
  1060    )
  1061    (func (export "f32.no_fold_le_if_to_abs") (param $x f32) (result f32)
  1062      (if (result f32) (f32.le (local.get $x) (f32.const -0.0))
  1063        (then (f32.neg (local.get $x))) (else (local.get $x))
  1064      )
  1065    )
  1066    (func (export "f32.no_fold_gt_if_to_abs") (param $x f32) (result f32)
  1067      (if (result f32) (f32.gt (local.get $x) (f32.const -0.0))
  1068        (then (local.get $x)) (else (f32.neg (local.get $x)))
  1069      )
  1070    )
  1071    (func (export "f32.no_fold_ge_if_to_abs") (param $x f32) (result f32)
  1072      (if (result f32) (f32.ge (local.get $x) (f32.const 0.0))
  1073        (then (local.get $x)) (else (f32.neg (local.get $x)))
  1074      )
  1075    )
  1076  
  1077    (func (export "f64.no_fold_lt_if_to_abs") (param $x f64) (result f64)
  1078      (if (result f64) (f64.lt (local.get $x) (f64.const 0.0))
  1079        (then (f64.neg (local.get $x))) (else (local.get $x))
  1080      )
  1081    )
  1082    (func (export "f64.no_fold_le_if_to_abs") (param $x f64) (result f64)
  1083      (if (result f64) (f64.le (local.get $x) (f64.const -0.0))
  1084        (then (f64.neg (local.get $x))) (else (local.get $x))
  1085      )
  1086    )
  1087    (func (export "f64.no_fold_gt_if_to_abs") (param $x f64) (result f64)
  1088      (if (result f64) (f64.gt (local.get $x) (f64.const -0.0))
  1089        (then (local.get $x)) (else (f64.neg (local.get $x)))
  1090      )
  1091    )
  1092    (func (export "f64.no_fold_ge_if_to_abs") (param $x f64) (result f64)
  1093      (if (result f64) (f64.ge (local.get $x) (f64.const 0.0))
  1094        (then (local.get $x)) (else (f64.neg (local.get $x)))
  1095      )
  1096    )
  1097  )
  1098  
  1099  (assert_return (invoke "f32.no_fold_lt_if_to_abs" (f32.const nan:0x200000)) (f32.const nan:0x200000))
  1100  (assert_return (invoke "f32.no_fold_lt_if_to_abs" (f32.const -nan)) (f32.const -nan))
  1101  (assert_return (invoke "f32.no_fold_lt_if_to_abs" (f32.const 0.0)) (f32.const 0.0))
  1102  (assert_return (invoke "f32.no_fold_lt_if_to_abs" (f32.const -0.0)) (f32.const -0.0))
  1103  (assert_return (invoke "f32.no_fold_le_if_to_abs" (f32.const nan:0x200000)) (f32.const nan:0x200000))
  1104  (assert_return (invoke "f32.no_fold_le_if_to_abs" (f32.const -nan)) (f32.const -nan))
  1105  (assert_return (invoke "f32.no_fold_le_if_to_abs" (f32.const 0.0)) (f32.const -0.0))
  1106  (assert_return (invoke "f32.no_fold_le_if_to_abs" (f32.const -0.0)) (f32.const 0.0))
  1107  (assert_return (invoke "f32.no_fold_gt_if_to_abs" (f32.const nan:0x200000)) (f32.const -nan:0x200000))
  1108  (assert_return (invoke "f32.no_fold_gt_if_to_abs" (f32.const -nan)) (f32.const nan))
  1109  (assert_return (invoke "f32.no_fold_gt_if_to_abs" (f32.const 0.0)) (f32.const -0.0))
  1110  (assert_return (invoke "f32.no_fold_gt_if_to_abs" (f32.const -0.0)) (f32.const 0.0))
  1111  (assert_return (invoke "f32.no_fold_ge_if_to_abs" (f32.const nan:0x200000)) (f32.const -nan:0x200000))
  1112  (assert_return (invoke "f32.no_fold_ge_if_to_abs" (f32.const -nan)) (f32.const nan))
  1113  (assert_return (invoke "f32.no_fold_ge_if_to_abs" (f32.const 0.0)) (f32.const 0.0))
  1114  (assert_return (invoke "f32.no_fold_ge_if_to_abs" (f32.const -0.0)) (f32.const -0.0))
  1115  (assert_return (invoke "f64.no_fold_lt_if_to_abs" (f64.const nan:0x4000000000000)) (f64.const nan:0x4000000000000))
  1116  (assert_return (invoke "f64.no_fold_lt_if_to_abs" (f64.const -nan)) (f64.const -nan))
  1117  (assert_return (invoke "f64.no_fold_lt_if_to_abs" (f64.const 0.0)) (f64.const 0.0))
  1118  (assert_return (invoke "f64.no_fold_lt_if_to_abs" (f64.const -0.0)) (f64.const -0.0))
  1119  (assert_return (invoke "f64.no_fold_le_if_to_abs" (f64.const nan:0x4000000000000)) (f64.const nan:0x4000000000000))
  1120  (assert_return (invoke "f64.no_fold_le_if_to_abs" (f64.const -nan)) (f64.const -nan))
  1121  (assert_return (invoke "f64.no_fold_le_if_to_abs" (f64.const 0.0)) (f64.const -0.0))
  1122  (assert_return (invoke "f64.no_fold_le_if_to_abs" (f64.const -0.0)) (f64.const 0.0))
  1123  (assert_return (invoke "f64.no_fold_gt_if_to_abs" (f64.const nan:0x4000000000000)) (f64.const -nan:0x4000000000000))
  1124  (assert_return (invoke "f64.no_fold_gt_if_to_abs" (f64.const -nan)) (f64.const nan))
  1125  (assert_return (invoke "f64.no_fold_gt_if_to_abs" (f64.const 0.0)) (f64.const -0.0))
  1126  (assert_return (invoke "f64.no_fold_gt_if_to_abs" (f64.const -0.0)) (f64.const 0.0))
  1127  (assert_return (invoke "f64.no_fold_ge_if_to_abs" (f64.const nan:0x4000000000000)) (f64.const -nan:0x4000000000000))
  1128  (assert_return (invoke "f64.no_fold_ge_if_to_abs" (f64.const -nan)) (f64.const nan))
  1129  (assert_return (invoke "f64.no_fold_ge_if_to_abs" (f64.const 0.0)) (f64.const 0.0))
  1130  (assert_return (invoke "f64.no_fold_ge_if_to_abs" (f64.const -0.0)) (f64.const -0.0))
  1131  
  1132  ;; Test for a historic spreadsheet bug.
  1133  ;; https://support.microsoft.com/en-us/kb/78113
  1134  
  1135  (module
  1136    (func (export "f32.incorrect_correction") (result f32)
  1137      (f32.sub (f32.sub (f32.add (f32.const 1.333) (f32.const 1.225)) (f32.const 1.333)) (f32.const 1.225))
  1138    )
  1139    (func (export "f64.incorrect_correction") (result f64)
  1140      (f64.sub (f64.sub (f64.add (f64.const 1.333) (f64.const 1.225)) (f64.const 1.333)) (f64.const 1.225))
  1141    )
  1142  )
  1143  
  1144  (assert_return (invoke "f32.incorrect_correction") (f32.const 0x1p-23))
  1145  (assert_return (invoke "f64.incorrect_correction") (f64.const -0x1p-52))
  1146  
  1147  ;; Test for a historical calculator bug.
  1148  ;; http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/articles.cgi?read=735
  1149  
  1150  (module
  1151    (func (export "calculate") (result f32)
  1152      (local $x f32)
  1153      (local $r f32)
  1154      (local $q f32)
  1155      (local $z0 f32)
  1156      (local $z1 f32)
  1157      (local.set $x (f32.const 156.25))
  1158      (local.set $r (f32.const 208.333333334))
  1159      (local.set $q (f32.const 1.77951304201))
  1160      (local.set $z0 (f32.div (f32.mul (f32.neg (local.get $r)) (local.get $x)) (f32.sub (f32.mul (local.get $x) (local.get $q)) (local.get $r))))
  1161      (local.set $z1 (f32.div (f32.mul (f32.neg (local.get $r)) (local.get $x)) (f32.sub (f32.mul (local.get $x) (local.get $q)) (local.get $r))))
  1162      (block (br_if 0 (f32.eq (local.get $z0) (local.get $z1))) (unreachable))
  1163      (local.get $z1)
  1164    )
  1165  )
  1166  
  1167  (assert_return (invoke "calculate") (f32.const -0x1.d2ed46p+8))
  1168  
  1169  (module
  1170    (func (export "calculate") (result f64)
  1171      (local $x f64)
  1172      (local $r f64)
  1173      (local $q f64)
  1174      (local $z0 f64)
  1175      (local $z1 f64)
  1176      (local.set $x (f64.const 156.25))
  1177      (local.set $r (f64.const 208.333333334))
  1178      (local.set $q (f64.const 1.77951304201))
  1179      (local.set $z0 (f64.div (f64.mul (f64.neg (local.get $r)) (local.get $x)) (f64.sub (f64.mul (local.get $x) (local.get $q)) (local.get $r))))
  1180      (local.set $z1 (f64.div (f64.mul (f64.neg (local.get $r)) (local.get $x)) (f64.sub (f64.mul (local.get $x) (local.get $q)) (local.get $r))))
  1181      (block (br_if 0 (f64.eq (local.get $z0) (local.get $z1))) (unreachable))
  1182      (local.get $z1)
  1183    )
  1184  )
  1185  
  1186  (assert_return (invoke "calculate") (f64.const -0x1.d2ed4d0218c93p+8))
  1187  
  1188  ;; Test that 0 - (-0 - x) is not optimized to x.
  1189  ;; https://llvm.org/bugs/show_bug.cgi?id=26746
  1190  
  1191  (module
  1192    (func (export "llvm_pr26746") (param $x f32) (result f32)
  1193      (f32.sub (f32.const 0.0) (f32.sub (f32.const -0.0) (local.get $x)))
  1194    )
  1195  )
  1196  
  1197  (assert_return (invoke "llvm_pr26746" (f32.const -0.0)) (f32.const 0.0))
  1198  
  1199  ;; Test for improperly reassociating an addition and a conversion.
  1200  ;; https://llvm.org/bugs/show_bug.cgi?id=27153
  1201  
  1202  (module
  1203    (func (export "llvm_pr27153") (param $x i32) (result f32)
  1204      (f32.add (f32.convert_i32_s (i32.and (local.get $x) (i32.const 268435455))) (f32.const -8388608.0))
  1205    )
  1206  )
  1207  
  1208  (assert_return (invoke "llvm_pr27153" (i32.const 33554434)) (f32.const 25165824.000000))
  1209  
  1210  ;; Test that (float)x + (float)y is not optimized to (float)(x + y) when unsafe.
  1211  ;; https://llvm.org/bugs/show_bug.cgi?id=27036
  1212  
  1213  (module
  1214    (func (export "llvm_pr27036") (param $x i32) (param $y i32) (result f32)
  1215      (f32.add (f32.convert_i32_s (i32.or (local.get $x) (i32.const -25034805)))
  1216               (f32.convert_i32_s (i32.and (local.get $y) (i32.const 14942208))))
  1217    )
  1218  )
  1219  
  1220  (assert_return (invoke "llvm_pr27036" (i32.const -25034805) (i32.const 14942208)) (f32.const -0x1.340068p+23))
  1221  
  1222  ;; Test for bugs in old versions of historic IEEE 754 platforms as reported in:
  1223  ;;
  1224  ;; N. L. Schryer. 1981. A Test of a Computer's Floating-Point Arithmetic Unit.
  1225  ;; Tech. Rep. Computer Science Technical Report 89, AT&T Bell Laboratories, Feb.
  1226  ;;
  1227  ;; specifically, the appendices describing IEEE systems with "The Past" sections
  1228  ;; describing specific bugs. The 0 < 0 bug is omitted here due to being already
  1229  ;; covered elsewhere.
  1230  (module
  1231    (func (export "thepast0") (param $a f64) (param $b f64) (param $c f64) (param $d f64) (result f64)
  1232      (f64.div (f64.mul (local.get $a) (local.get $b)) (f64.mul (local.get $c) (local.get $d)))
  1233    )
  1234  
  1235    (func (export "thepast1") (param $a f64) (param $b f64) (param $c f64) (result f64)
  1236      (f64.sub (f64.mul (local.get $a) (local.get $b)) (local.get $c))
  1237    )
  1238  
  1239    (func (export "thepast2") (param $a f32) (param $b f32) (param $c f32) (result f32)
  1240      (f32.mul (f32.mul (local.get $a) (local.get $b)) (local.get $c))
  1241    )
  1242  )
  1243  
  1244  (assert_return (invoke "thepast0" (f64.const 0x1p-1021) (f64.const 0x1.fffffffffffffp-1) (f64.const 0x1p1) (f64.const 0x1p-1)) (f64.const 0x1.fffffffffffffp-1022))
  1245  (assert_return (invoke "thepast1" (f64.const 0x1p-54) (f64.const 0x1.fffffffffffffp-1) (f64.const 0x1p-54)) (f64.const -0x1p-107))
  1246  (assert_return (invoke "thepast2" (f32.const 0x1p-125) (f32.const 0x1p-1) (f32.const 0x1p0)) (f32.const 0x1p-126))
  1247  
  1248  ;; Test for floating point tolerances observed in some GPUs.
  1249  ;; https://community.amd.com/thread/145582
  1250  
  1251  (module
  1252    (func (export "inverse") (param $x f32) (result f32)
  1253      (f32.div (f32.const 1.0) (local.get $x))
  1254    )
  1255  )
  1256  
  1257  (assert_return (invoke "inverse" (f32.const 96.0)) (f32.const 0x1.555556p-7))
  1258  
  1259  ;; Test for incorrect rounding on sqrt(4.0).
  1260  ;; http://www.askvg.com/microsoft-windows-calculator-bug/
  1261  
  1262  (module
  1263    (func (export "f32_sqrt_minus_2") (param $x f32) (result f32)
  1264      (f32.sub (f32.sqrt (local.get $x)) (f32.const 2.0))
  1265    )
  1266  
  1267    (func (export "f64_sqrt_minus_2") (param $x f64) (result f64)
  1268      (f64.sub (f64.sqrt (local.get $x)) (f64.const 2.0))
  1269    )
  1270  )
  1271  
  1272  (assert_return (invoke "f32_sqrt_minus_2" (f32.const 4.0)) (f32.const 0.0))
  1273  (assert_return (invoke "f64_sqrt_minus_2" (f64.const 4.0)) (f64.const 0.0))
  1274  
  1275  ;; Test that 1.0 / (1.0 / x) is not optimized to x.
  1276  
  1277  (module
  1278    (func (export "f32.no_fold_recip_recip") (param $x f32) (result f32)
  1279      (f32.div (f32.const 1.0) (f32.div (f32.const 1.0) (local.get $x))))
  1280  
  1281    (func (export "f64.no_fold_recip_recip") (param $x f64) (result f64)
  1282      (f64.div (f64.const 1.0) (f64.div (f64.const 1.0) (local.get $x))))
  1283  )
  1284  
  1285  (assert_return (invoke "f32.no_fold_recip_recip" (f32.const -0x1.e8bf18p+65)) (f32.const -0x1.e8bf16p+65))
  1286  (assert_return (invoke "f32.no_fold_recip_recip" (f32.const 0x1.e24248p-77)) (f32.const 0x1.e24246p-77))
  1287  (assert_return (invoke "f32.no_fold_recip_recip" (f32.const 0x1.caf0e8p-64)) (f32.const 0x1.caf0eap-64))
  1288  (assert_return (invoke "f32.no_fold_recip_recip" (f32.const -0x1.e66982p+4)) (f32.const -0x1.e66984p+4))
  1289  (assert_return (invoke "f32.no_fold_recip_recip" (f32.const 0x1.f99916p+70)) (f32.const 0x1.f99914p+70))
  1290  
  1291  (assert_return (invoke "f32.no_fold_recip_recip" (f32.const -0x0p+0)) (f32.const -0x0p+0))
  1292  (assert_return (invoke "f32.no_fold_recip_recip" (f32.const 0x0p+0)) (f32.const 0x0p+0))
  1293  (assert_return (invoke "f32.no_fold_recip_recip" (f32.const -inf)) (f32.const -inf))
  1294  (assert_return (invoke "f32.no_fold_recip_recip" (f32.const inf)) (f32.const inf))
  1295  
  1296  (assert_return (invoke "f64.no_fold_recip_recip" (f64.const -0x1.d81248dda63dp+148)) (f64.const -0x1.d81248dda63d1p+148))
  1297  (assert_return (invoke "f64.no_fold_recip_recip" (f64.const -0x1.f4750312039e3p+66)) (f64.const -0x1.f4750312039e2p+66))
  1298  (assert_return (invoke "f64.no_fold_recip_recip" (f64.const 0x1.fa50630eec7f6p+166)) (f64.const 0x1.fa50630eec7f5p+166))
  1299  (assert_return (invoke "f64.no_fold_recip_recip" (f64.const 0x1.db0598617ba92p-686)) (f64.const 0x1.db0598617ba91p-686))
  1300  (assert_return (invoke "f64.no_fold_recip_recip" (f64.const 0x1.85f1638a0c82bp+902)) (f64.const 0x1.85f1638a0c82ap+902))
  1301  
  1302  (assert_return (invoke "f64.no_fold_recip_recip" (f64.const -0x0p+0)) (f64.const -0x0p+0))
  1303  (assert_return (invoke "f64.no_fold_recip_recip" (f64.const 0x0p+0)) (f64.const 0x0p+0))
  1304  (assert_return (invoke "f64.no_fold_recip_recip" (f64.const -inf)) (f64.const -inf))
  1305  (assert_return (invoke "f64.no_fold_recip_recip" (f64.const inf)) (f64.const inf))
  1306  
  1307  ;; Test that (x+y) * (x-y) is not optimized to x*x - y*y.
  1308  
  1309  (module
  1310    (func (export "f32.no_algebraic_factoring") (param $x f32) (param $y f32) (result f32)
  1311      (f32.mul (f32.add (local.get $x) (local.get $y))
  1312               (f32.sub (local.get $x) (local.get $y))))
  1313  
  1314    (func (export "f64.no_algebraic_factoring") (param $x f64) (param $y f64) (result f64)
  1315      (f64.mul (f64.add (local.get $x) (local.get $y))
  1316               (f64.sub (local.get $x) (local.get $y))))
  1317  )
  1318  
  1319  (assert_return (invoke "f32.no_algebraic_factoring" (f32.const -0x1.ef678ep-55) (f32.const 0x1.c160b8p-54)) (f32.const -0x1.129402p-107))
  1320  (assert_return (invoke "f32.no_algebraic_factoring" (f32.const -0x1.2d76bcp+24) (f32.const 0x1.f4089cp+24)) (f32.const -0x1.36d89ap+49))
  1321  (assert_return (invoke "f32.no_algebraic_factoring" (f32.const 0x1.7ca2b2p+45) (f32.const -0x1.08513cp+47)) (f32.const -0x1.db10dep+93))
  1322  (assert_return (invoke "f32.no_algebraic_factoring" (f32.const 0x1.7d5e3p+17) (f32.const -0x1.c783b4p+7)) (f32.const 0x1.1c10a6p+35))
  1323  (assert_return (invoke "f32.no_algebraic_factoring" (f32.const -0x1.daf96p+7) (f32.const -0x1.dac6bp+19)) (f32.const -0x1.b8422ep+39))
  1324  
  1325  (assert_return (invoke "f64.no_algebraic_factoring" (f64.const 0x1.e17c0a02ac6b5p-476) (f64.const 0x1.e8f13f1fcdc14p-463)) (f64.const -0x1.d2ec518f62863p-925))
  1326  (assert_return (invoke "f64.no_algebraic_factoring" (f64.const 0x1.971b55a57e3a3p-377) (f64.const 0x1.edeb4233c1b27p-399)) (f64.const 0x1.43b3f69fb258bp-753))
  1327  (assert_return (invoke "f64.no_algebraic_factoring" (f64.const -0x1.c3b9dc02472fap-378) (f64.const -0x1.74e9faebaff14p-369)) (f64.const -0x1.0f9c07e8caa25p-737))
  1328  (assert_return (invoke "f64.no_algebraic_factoring" (f64.const -0x1.afaf4688ed019p+179) (f64.const 0x1.b07171cb49e94p+188)) (f64.const -0x1.6d3f2e2bebcf7p+377))
  1329  (assert_return (invoke "f64.no_algebraic_factoring" (f64.const 0x1.4377a98948f12p+114) (f64.const -0x1.500c05bd24c97p+90)) (f64.const 0x1.98b72dbf7bf72p+228))
  1330  
  1331  ;; Test that x*x - y*y is not optimized to (x+y) * (x-y).
  1332  
  1333  (module
  1334    (func (export "f32.no_algebraic_factoring") (param $x f32) (param $y f32) (result f32)
  1335      (f32.sub (f32.mul (local.get $x) (local.get $x))
  1336               (f32.mul (local.get $y) (local.get $y))))
  1337  
  1338    (func (export "f64.no_algebraic_factoring") (param $x f64) (param $y f64) (result f64)
  1339      (f64.sub (f64.mul (local.get $x) (local.get $x))
  1340               (f64.mul (local.get $y) (local.get $y))))
  1341  )
  1342  
  1343  (assert_return (invoke "f32.no_algebraic_factoring" (f32.const 0x1.8e2c14p-46) (f32.const 0x1.bad59ap-39)) (f32.const -0x1.7efe5p-77))
  1344  (assert_return (invoke "f32.no_algebraic_factoring" (f32.const -0x1.7ef192p+41) (f32.const -0x1.db184ap+33)) (f32.const 0x1.1e6932p+83))
  1345  (assert_return (invoke "f32.no_algebraic_factoring" (f32.const 0x1.7eb458p-12) (f32.const -0x1.52c498p-13)) (f32.const 0x1.cc0bc6p-24))
  1346  (assert_return (invoke "f32.no_algebraic_factoring" (f32.const 0x1.2675c6p-44) (f32.const -0x1.edd31ap-46)) (f32.const 0x1.17294cp-88))
  1347  (assert_return (invoke "f32.no_algebraic_factoring" (f32.const 0x1.9a5f92p+51) (f32.const -0x1.2b0098p+52)) (f32.const -0x1.7189a6p+103))
  1348  
  1349  (assert_return (invoke "f64.no_algebraic_factoring" (f64.const 0x1.749a128f18f69p+356) (f64.const -0x1.0bc97ee1354e1p+337)) (f64.const 0x1.0f28115518d74p+713))
  1350  (assert_return (invoke "f64.no_algebraic_factoring" (f64.const -0x1.2dab01b2215eap+309) (f64.const -0x1.e12b288bff2bdp+331)) (f64.const -0x1.c4319ad25d201p+663))
  1351  (assert_return (invoke "f64.no_algebraic_factoring" (f64.const 0x1.3ed898431e102p+42) (f64.const -0x1.c409183fa92e6p+39)) (f64.const 0x1.80a611103c71dp+84))
  1352  (assert_return (invoke "f64.no_algebraic_factoring" (f64.const -0x1.be663e4c0e4b2p+182) (f64.const -0x1.da85703760d25p+166)) (f64.const 0x1.853434f1a2ffep+365))
  1353  (assert_return (invoke "f64.no_algebraic_factoring" (f64.const -0x1.230e09952df1cp-236) (f64.const -0x1.fa2752adfadc9p-237)) (f64.const 0x1.42e43156bd1b8p-474))
  1354  
  1355  ;; Test that platforms where SIMD instructions flush subnormals don't implicitly
  1356  ;; optimize using SIMD instructions.
  1357  
  1358  (module
  1359    (memory (data
  1360      "\01\00\00\00\01\00\00\80\01\00\00\00\01\00\00\80"
  1361      "\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00"
  1362      "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"
  1363    ))
  1364  
  1365    (func (export "f32.simple_x4_sum")
  1366      (param $i i32)
  1367      (param $j i32)
  1368      (param $k i32)
  1369      (local $x0 f32) (local $x1 f32) (local $x2 f32) (local $x3 f32)
  1370      (local $y0 f32) (local $y1 f32) (local $y2 f32) (local $y3 f32)
  1371      (local.set $x0 (f32.load offset=0 (local.get $i)))
  1372      (local.set $x1 (f32.load offset=4 (local.get $i)))
  1373      (local.set $x2 (f32.load offset=8 (local.get $i)))
  1374      (local.set $x3 (f32.load offset=12 (local.get $i)))
  1375      (local.set $y0 (f32.load offset=0 (local.get $j)))
  1376      (local.set $y1 (f32.load offset=4 (local.get $j)))
  1377      (local.set $y2 (f32.load offset=8 (local.get $j)))
  1378      (local.set $y3 (f32.load offset=12 (local.get $j)))
  1379      (f32.store offset=0 (local.get $k) (f32.add (local.get $x0) (local.get $y0)))
  1380      (f32.store offset=4 (local.get $k) (f32.add (local.get $x1) (local.get $y1)))
  1381      (f32.store offset=8 (local.get $k) (f32.add (local.get $x2) (local.get $y2)))
  1382      (f32.store offset=12 (local.get $k) (f32.add (local.get $x3) (local.get $y3)))
  1383    )
  1384  
  1385    (func (export "f32.load")
  1386      (param $k i32) (result f32)
  1387      (f32.load (local.get $k))
  1388    )
  1389  )
  1390  
  1391  (assert_return (invoke "f32.simple_x4_sum" (i32.const 0) (i32.const 16) (i32.const 32)))
  1392  (assert_return (invoke "f32.load" (i32.const 32)) (f32.const 0x1p-148))
  1393  (assert_return (invoke "f32.load" (i32.const 36)) (f32.const 0x0p+0))
  1394  (assert_return (invoke "f32.load" (i32.const 40)) (f32.const 0x1p-149))
  1395  (assert_return (invoke "f32.load" (i32.const 44)) (f32.const -0x1p-149))
  1396  
  1397  (module
  1398    (memory (data
  1399      "\01\00\00\00\00\00\00\00\01\00\00\00\00\00\00\80\01\00\00\00\00\00\00\00\01\00\00\00\00\00\00\80"
  1400      "\01\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"
  1401      "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"
  1402    ))
  1403  
  1404    (func (export "f64.simple_x4_sum")
  1405      (param $i i32)
  1406      (param $j i32)
  1407      (param $k i32)
  1408      (local $x0 f64) (local $x1 f64) (local $x2 f64) (local $x3 f64)
  1409      (local $y0 f64) (local $y1 f64) (local $y2 f64) (local $y3 f64)
  1410      (local.set $x0 (f64.load offset=0 (local.get $i)))
  1411      (local.set $x1 (f64.load offset=8 (local.get $i)))
  1412      (local.set $x2 (f64.load offset=16 (local.get $i)))
  1413      (local.set $x3 (f64.load offset=24 (local.get $i)))
  1414      (local.set $y0 (f64.load offset=0 (local.get $j)))
  1415      (local.set $y1 (f64.load offset=8 (local.get $j)))
  1416      (local.set $y2 (f64.load offset=16 (local.get $j)))
  1417      (local.set $y3 (f64.load offset=24 (local.get $j)))
  1418      (f64.store offset=0 (local.get $k) (f64.add (local.get $x0) (local.get $y0)))
  1419      (f64.store offset=8 (local.get $k) (f64.add (local.get $x1) (local.get $y1)))
  1420      (f64.store offset=16 (local.get $k) (f64.add (local.get $x2) (local.get $y2)))
  1421      (f64.store offset=24 (local.get $k) (f64.add (local.get $x3) (local.get $y3)))
  1422    )
  1423  
  1424    (func (export "f64.load")
  1425      (param $k i32) (result f64)
  1426      (f64.load (local.get $k))
  1427    )
  1428  )
  1429  
  1430  (assert_return (invoke "f64.simple_x4_sum" (i32.const 0) (i32.const 32) (i32.const 64)))
  1431  (assert_return (invoke "f64.load" (i32.const 64)) (f64.const 0x0.0000000000001p-1021))
  1432  (assert_return (invoke "f64.load" (i32.const 72)) (f64.const 0x0p+0))
  1433  (assert_return (invoke "f64.load" (i32.const 80)) (f64.const 0x0.0000000000001p-1022))
  1434  (assert_return (invoke "f64.load" (i32.const 88)) (f64.const -0x0.0000000000001p-1022))
  1435  
  1436  ;; Test that plain summation is not reassociated, and that Kahan summation
  1437  ;; isn't optimized into plain summation.
  1438  
  1439  (module
  1440    (memory (data
  1441      "\c4\c5\57\24\a5\84\c8\0b\6d\b8\4b\2e\f2\76\17\1c\ca\4a\56\1e\1b\6e\71\22"
  1442      "\5d\17\1e\6e\bf\cd\14\5c\c7\21\55\51\39\9c\1f\b2\51\f0\a3\93\d7\c1\2c\ae"
  1443      "\7e\a8\28\3a\01\21\f4\0a\58\93\f8\42\77\9f\83\39\6a\5f\ba\f7\0a\d8\51\6a"
  1444      "\34\ca\ad\c6\34\0e\d8\26\dc\4c\33\1c\ed\29\90\a8\78\0f\d1\ce\76\31\23\83"
  1445      "\b8\35\e8\f2\44\b0\d3\a1\fc\bb\32\e1\b0\ba\69\44\09\d6\d9\7d\ff\2e\c0\5a"
  1446      "\36\14\33\14\3e\a9\fa\87\6d\8b\bc\ce\9d\a7\fd\c4\e9\85\3f\dd\d7\e1\18\a6"
  1447      "\50\26\72\6e\3f\73\0f\f8\12\93\23\34\61\76\12\48\c0\9b\05\93\eb\ac\86\de"
  1448      "\94\3e\55\e8\8c\e8\dd\e4\fc\95\47\be\56\03\21\20\4c\e6\bf\7b\f6\7f\d5\ba"
  1449      "\73\1c\c1\14\8f\c4\27\96\b3\bd\33\ff\78\41\5f\c0\5a\ce\f6\67\6e\73\9a\17"
  1450      "\66\70\03\f8\ce\27\a3\52\b2\9f\3b\bf\fb\ae\ed\d3\5a\f8\37\57\f0\f5\6e\ef"
  1451      "\b1\4d\70\3d\54\a7\01\9a\85\08\48\91\f5\9d\0c\60\87\5b\d9\54\1e\51\6d\88"
  1452      "\8e\08\8c\a5\71\3a\56\08\67\46\8f\8f\13\2a\2c\ec\2c\1f\b4\62\2b\6f\41\0a"
  1453      "\c4\65\42\a2\31\6b\2c\7d\3e\bb\75\ac\86\97\30\d9\48\cd\9a\1f\56\c4\c6\e4"
  1454      "\12\c0\9d\fb\ee\02\8c\ce\1c\f2\1e\a1\78\23\db\c4\1e\49\03\d3\71\cc\08\50"
  1455      "\c5\d8\5c\ed\d5\b5\65\ac\b5\c9\21\d2\c9\29\76\de\f0\30\1a\5b\3c\f2\3b\db"
  1456      "\3a\39\82\3a\16\08\6f\a8\f1\be\69\69\99\71\a6\05\d3\14\93\2a\16\f2\2f\11"
  1457      "\c7\7e\20\bb\91\44\ee\f8\e4\01\53\c0\b9\7f\f0\bf\f0\03\9c\6d\b1\df\a2\44"
  1458      "\01\6d\6b\71\2b\5c\b3\21\19\46\5e\8f\db\91\d3\7c\78\6b\b7\12\00\8f\eb\bd"
  1459      "\8a\f5\d4\2e\c4\c1\1e\df\73\63\59\47\49\03\0a\b7\cf\24\cf\9c\0e\44\7a\9e"
  1460      "\14\fb\42\bf\9d\39\30\9e\a0\ab\2f\d1\ae\9e\6a\83\43\e3\55\7d\85\bf\63\8a"
  1461      "\f8\96\10\1f\fe\6d\e7\22\1b\e1\69\46\8a\44\c8\c8\f9\0c\2b\19\07\a5\02\3e"
  1462      "\f2\30\10\9a\85\8a\5f\ef\81\45\a0\77\b1\03\10\73\4b\ae\98\9d\47\bf\9a\2d"
  1463      "\3a\d5\0f\03\66\e3\3d\53\d9\40\ce\1f\6f\32\2f\21\2b\23\21\6c\62\d4\a7\3e"
  1464      "\a8\ce\28\31\2d\00\3d\67\5e\af\a0\cf\2e\d2\b9\6b\84\eb\69\08\3c\62\36\be"
  1465      "\12\fd\36\7f\88\3e\ad\bc\0b\c0\41\c4\50\b6\e3\50\31\e8\ce\e2\96\65\55\9c"
  1466      "\16\46\e6\b0\2d\3a\e8\81\05\b0\bf\34\f7\bc\10\1c\fb\cc\3c\f1\85\97\42\9f"
  1467      "\eb\14\8d\3c\bf\d7\17\88\49\9d\8b\2b\b2\3a\83\d1\4f\04\9e\a1\0f\ad\08\9d"
  1468      "\54\af\d1\82\c3\ec\32\2f\02\8f\05\21\2d\a2\b7\e4\f4\6f\2e\81\2b\0b\9c\fc"
  1469      "\cb\fe\74\02\f9\db\f4\f3\ea\00\a8\ec\d1\99\74\26\dd\d6\34\d5\25\b1\46\dd"
  1470      "\9c\aa\71\f5\60\b0\88\c8\e0\0b\59\5a\25\4f\29\66\f9\e3\2e\fe\e9\da\e5\18"
  1471      "\4f\27\62\f4\ce\a4\21\95\74\c7\57\64\27\9a\4c\fd\54\7d\61\ce\c3\ac\87\46"
  1472      "\9c\fa\ff\09\ca\79\97\67\24\74\ca\d4\21\83\26\25\19\12\37\64\19\e5\65\e0"
  1473      "\74\75\8e\dd\c8\ef\74\c7\d8\21\2b\79\04\51\46\65\60\03\5d\fa\d8\f4\65\a4"
  1474      "\9e\5d\23\da\d7\8a\92\80\a4\de\78\3c\f1\57\42\6d\cd\c9\2f\d5\a4\9e\ab\40"
  1475      "\f4\cb\1b\d7\a3\ca\fc\eb\a7\01\b2\9a\69\4e\46\9b\18\4e\dd\79\a7\aa\a6\52"
  1476      "\39\1e\ef\30\cc\9b\bd\5b\ee\4c\21\6d\30\00\72\b0\46\5f\08\cf\c5\b9\e0\3e"
  1477      "\c2\b3\0c\dc\8e\64\de\19\42\79\cf\43\ea\43\5d\8e\88\f7\ab\15\dc\3f\c8\67"
  1478      "\20\db\b8\64\b1\47\1f\de\f2\cb\3f\59\9f\d8\46\90\dc\ae\2f\22\f9\e2\31\89"
  1479      "\d9\9c\1c\4c\d3\a9\4a\57\84\9c\9f\ea\2c\3c\ae\3c\c3\1e\8b\e5\4e\17\01\25"
  1480      "\db\34\46\5f\15\ea\05\0c\7c\d9\45\8c\19\d0\73\8a\96\16\dd\44\f9\05\b7\5b"
  1481      "\71\b0\e6\21\36\5f\75\89\91\73\75\ab\7d\ae\d3\73\ec\37\c6\ea\55\75\ef\ea"
  1482      "\ab\8b\7b\11\dc\6d\1a\b2\6a\c4\25\cf\aa\e3\9f\49\49\89\cb\37\9b\0a\a7\01"
  1483      "\60\70\dc\b7\c8\83\e1\42\f5\be\ad\62\94\ad\8d\a1"
  1484    ))
  1485  
  1486    (func (export "f32.kahan_sum") (param $p i32) (param $n i32) (result f32)
  1487      (local $sum f32)
  1488      (local $c f32)
  1489      (local $t f32)
  1490      (block $exit
  1491        (loop $top
  1492          (local.set $t
  1493            (f32.sub
  1494              (f32.sub
  1495                (local.tee $sum
  1496                  (f32.add
  1497                    (local.get $c)
  1498                    (local.tee $t
  1499                      (f32.sub (f32.load (local.get $p)) (local.get $t))
  1500                    )
  1501                  )
  1502                )
  1503                (local.get $c)
  1504              )
  1505              (local.get $t)
  1506            )
  1507          )
  1508          (local.set $p (i32.add (local.get $p) (i32.const 4)))
  1509          (local.set $c (local.get $sum))
  1510          (br_if $top (local.tee $n (i32.add (local.get $n) (i32.const -1))))
  1511        )
  1512      )
  1513      (local.get $sum)
  1514    )
  1515  
  1516    (func (export "f32.plain_sum") (param $p i32) (param $n i32) (result f32)
  1517      (local $sum f32)
  1518      (block $exit
  1519        (loop $top
  1520          (local.set $sum (f32.add (local.get $sum) (f32.load (local.get $p))))
  1521          (local.set $p (i32.add (local.get $p) (i32.const 4)))
  1522          (local.set $n (i32.add (local.get $n) (i32.const -1)))
  1523          (br_if $top (local.get $n))
  1524        )
  1525      )
  1526      (local.get $sum)
  1527    )
  1528  )
  1529  
  1530  (assert_return (invoke "f32.kahan_sum" (i32.const 0) (i32.const 256)) (f32.const -0x1.101a1ap+104))
  1531  (assert_return (invoke "f32.plain_sum" (i32.const 0) (i32.const 256)) (f32.const -0x1.a0343ap+103))
  1532  
  1533  (module
  1534    (memory (data "\13\05\84\42\5d\a2\2c\c6\43\db\55\a9\cd\da\55\e3\73\fc\58\d6\ba\d5\00\fd\83\35\42\88\8b\13\5d\38\4a\47\0d\72\73\a1\1a\ef\c4\45\17\57\d8\c9\46\e0\8d\6c\e1\37\70\c8\83\5b\55\5e\5a\2d\73\1e\56\c8\e1\6d\69\14\78\0a\8a\5a\64\3a\09\c7\a8\87\c5\f0\d3\5d\e6\03\fc\93\be\26\ca\d6\a9\91\60\bd\b0\ed\ae\f7\30\7e\92\3a\6f\a7\59\8e\aa\7d\bf\67\58\2a\54\f8\4e\fe\ed\35\58\a6\51\bf\42\e5\4b\66\27\24\6d\7f\42\2d\28\92\18\ec\08\ae\e7\55\da\b1\a6\65\a5\72\50\47\1b\b8\a9\54\d7\a6\06\5b\0f\42\58\83\8a\17\82\c6\10\43\a0\c0\2e\6d\bc\5a\85\53\72\7f\ad\44\bc\30\3c\55\b2\24\9a\74\3a\9e\e1\d8\0f\70\fc\a9\3a\cd\93\4b\ec\e3\7e\dd\5d\27\cd\f8\a0\9d\1c\11\c0\57\2e\fd\c8\13\32\cc\3a\1a\7d\a3\41\55\ed\c3\82\49\2a\04\1e\ef\73\b9\2e\2e\e3\5f\f4\df\e6\b2\33\0c\39\3f\6f\44\6a\03\c1\42\b9\fa\b1\c8\ed\a5\58\99\7f\ed\b4\72\9e\79\eb\fb\43\82\45\aa\bb\95\d2\ff\28\9e\f6\a1\ad\95\d6\55\95\0d\6f\60\11\c7\78\3e\49\f2\7e\48\f4\a2\71\d0\13\8e\b3\de\99\52\e3\45\74\ea\76\0e\1b\2a\c8\ee\14\01\c4\50\5b\36\3c\ef\ba\72\a2\a6\08\f8\7b\36\9d\f9\ef\0b\c7\56\2d\5c\f0\9d\5d\de\fc\b8\ad\0f\64\0e\97\15\32\26\c2\31\e6\05\1e\ef\cb\17\1b\6d\15\0b\74\5d\d3\2e\f8\6b\86\b4\ba\73\52\53\99\a9\76\20\45\c9\40\80\6b\14\ed\a1\fa\80\46\e6\26\d2\e6\98\c4\57\bf\c4\1c\a4\90\7a\36\94\14\ba\15\89\6e\e6\9c\37\8c\f4\de\12\22\5d\a1\79\50\67\0d\3d\7a\e9\d4\aa\2e\7f\2a\7a\30\3d\ea\5d\12\48\fe\e1\18\cd\a4\57\a2\87\3e\b6\9a\8b\db\da\9d\78\9c\cf\8d\b1\4f\90\b4\34\e0\9d\f6\ca\fe\4c\3b\78\6d\0a\5c\18\9f\61\b9\dd\b4\e0\0f\76\e0\1b\69\0d\5e\58\73\70\5e\0e\2d\a1\7d\ff\20\eb\91\34\92\ac\38\72\2a\1f\8e\71\2e\6a\f1\af\c7\27\70\d9\c4\57\f7\d2\3c\1d\b8\f0\f0\64\cf\dc\ae\be\a3\cc\3e\22\7d\4e\69\21\63\17\ed\03\02\54\9a\0f\50\4e\13\5a\35\a1\22\a4\df\86\c2\74\79\16\b8\69\69\a0\52\5d\11\64\bd\5b\93\fc\69\a0\f4\13\d0\81\51\dd\fa\0c\15\c3\7a\c9\62\7a\a9\1d\c9\e6\5a\b3\5b\97\02\3c\64\22\12\3c\22\90\64\2d\30\54\4c\b4\a1\22\09\57\22\5e\8e\38\2b\02\a8\ae\f6\be\0d\2b\f2\03\ad\fa\10\01\71\77\2a\30\02\95\f6\00\3e\d0\c4\8d\34\19\50\21\0a\bc\50\da\3c\30\d6\3a\31\94\8d\3a\fe\ef\14\57\9d\4b\93\00\96\24\0c\6f\fd\bc\23\76\02\6c\eb\52\72\80\11\7e\80\3a\13\12\38\1d\38\49\95\40\27\8a\44\7b\e8\dc\6d\8c\8c\8e\3c\b5\b3\18\0e\f6\08\1a\84\41\35\ff\8b\b8\93\40\ea\e1\51\1d\89\a5\8d\42\68\29\ea\2f\c1\7a\52\eb\90\5d\4d\d6\80\e3\d7\75\48\ce\ed\d3\01\1c\8d\5b\a5\94\0d\78\cf\f1\06\13\2f\98\02\a4\6d\2e\6c\f2\d5\74\29\89\4c\f9\03\f5\c7\18\ad\7a\f0\68\f8\5c\d6\59\87\6e\d6\3f\06\be\86\20\e3\41\91\22\f3\6e\8b\f0\68\1c\57\a7\fc\b0\7c\9e\99\0b\96\1a\89\5f\e6\0d\7c\08\51\a0\a2\67\9a\47\00\93\6b\f9\28\f0\68\db\62\f1\e0\65\2c\53\33\e0\a7\ca\11\42\30\f6\af\01\c1\65\3d\32\01\6f\ab\2e\be\d3\8b\be\14\c3\ff\ec\fb\f0\f9\c5\0c\05\6f\01\09\6b\e3\34\31\0c\1f\66\a6\42\bc\1a\87\49\16\16\8c\b0\90\0d\34\8c\0a\e1\09\5e\10\a4\6b\56\cc\f0\c9\bb\dc\b8\5c\ce\f6\cc\8d\75\7e\b3\07\88\04\2f\b4\5e\c9\e3\4a\23\73\19\62\6c\9a\03\76\44\86\9c\60\fc\db\72\8f\27\a0\dd\b3\c5\da\ff\f9\ec\6a\b1\7b\d3\cf\50\37\c9\7a\78\0c\e4\3a\b6\f5\e6\f4\98\6e\42\7d\35\73\8b\45\c0\56\97\cd\6d\ce\cf\ad\31\b3\c3\54\fa\ef\d5\c0\f4\6a\5f\54\e7\49\3e\33\0a\30\38\fd\d9\05\ff\a5\3f\57\46\14\b5\91\17\ca\6b\98\23\7a\65\b3\6c\02\b4\cc\79\5d\58\d8\b3\d5\94\ae\f4\6d\75\65\f7\92\bf\7e\47\4c\3c\ee\db\ac\f1\32\5d\fb\6f\41\1c\34\c8\83\4f\c2\58\01\be\05\3e\66\16\a6\04\6d\5d\4f\86\09\27\82\25\12\cd\3a\cd\ce\6b\bc\ca\ac\28\9b\ee\6a\25\86\9e\45\70\c6\d2\bd\3b\7d\42\e5\27\af\c7\1d\f4\81\c8\b3\76\8a\a8\36\a3\ae\2a\e6\18\e1\36\22\ad\f6\25\72\b0\39\8b\01\9a\22\7b\84\c3\2d\5f\72\a4\98\ac\15\70\e7\d4\18\e2\7d\d2\30\7c\33\08\cd\ca\c4\22\85\88\75\81\c6\4a\74\58\8d\e0\e8\ac\c5\ab\75\5a\f4\28\12\f0\18\45\52\f2\97\b2\93\41\6f\8d\7f\db\70\fb\a3\5d\1f\a7\8d\98\20\2b\22\9f\3a\01\b5\8b\1b\d2\cb\14\03\0e\14\14\d2\19\5a\1f\ce\5e\cd\81\79\15\01\ca\de\73\74\8c\56\20\9f\77\2d\25\16\f6\61\51\1d\a4\8e\9b\98\a5\c6\ec\a8\45\57\82\59\78\0d\90\b4\df\51\b0\c3\82\94\cc\b3\53\09\15\6d\96\6c\3a\40\47\b7\4a\7a\05\2f\a1\1e\8c\9d\a0\20\88\fb\52\b7\9f\f3\f3\bb\5f\e7\8a\61\a7\21\b1\ac\fa\09\aa\a4\6c\bc\24\80\ba\2a\e9\65\ff\70\ff\cc\fa\65\87\76\f3\c5\15\ce\cb\e8\42\31\00\0c\91\57\d9\e0\9d\35\54\24\ad\a4\d8\f9\08\67\63\c8\cf\81\dd\90\a2\d7\c4\07\4a\e6\10\6f\67\e7\27\d4\23\59\18\f2\a8\9d\5f\d8\94\30\aa\54\86\4f\87\9d\82\b5\26\ca\a6\96\bf\cf\55\f9\9d\37\01\19\48\43\c5\94\6c\f3\74\97\58\4c\3c\9d\08\e8\04\c2\58\30\76\e1\a0\f8\ea\e9\c5\ae\cf\78\9e\a9\0c\ac\b3\44\42\e0\bc\5d\1b\9c\49\58\4a\1c\19\49\c1\3a\ea\f5\eb\3b\81\a9\4b\70\0c\cc\9e\1a\d3\2f\b7\52\2f\20\3b\eb\64\51\1d\a0\2d\b2\3e\be\13\85\48\92\32\2e\db\5c\a1\e7\8c\45\91\35\01\0a\93\c2\eb\09\ce\f3\d2\22\24\d0\8c\cc\1d\9d\38\c8\4d\e3\82\cc\64\15\06\2d\e7\01\2f\ab\bb\b5\04\4c\92\1c\7a\d6\3f\e8\5f\31\15\0c\dc\e4\31\b4\c4\25\3e\2a\aa\00\9e\c8\e5\21\7a\7f\29\f1\c0\af\1d\5e\e8\63\39\ad\f8\7e\6c\c8\c5\7f\c2\a8\97\27\0a\d9\f4\21\6a\ea\03\09\fb\f7\96\3b\83\79\5f\7c\4b\30\9f\56\35\de\b4\73\d4\95\f0\14\c3\74\2f\0d\a3\1d\4e\8d\31\24\b3\1a\84\85\62\5a\7b\3c\14\39\17\e6\6d\eb\37\c2\00\58\5b\0b\e3\3c\8a\62\e1\f8\35\4b\56\e2\87\60\8b\be\a7\38\91\77\54\a9\5a\24\25\90\9f\a5\42\77\f3\5c\39\df\ff\74\07\76\a1\cd\1f\62\0b\81\81\68\af\05\c1\c0\7f\26\ee\c0\91\a3\6a\7d\29\61\45\27\e5\57\88\dc\0d\97\04\1a\33\a9\44\8a\da\02\10\45\3f\8e\55\a6\76\8c\4d\e3\f1\89\83\c8\d0\f8\9b\50\77\9f\47\df\4c\9c\66\0d\aa\18\b8\5f\4f\c4\01\ce\dc\84\ac\46\9e\69\e1\76\45\6b\61\89\e4\5d\94\bb\11\83\9f\78\d8\0a\d2\f5\7e\5d\43\ea\bc\10\f1\3a\c9\e2\64\fb\53\65\d0\c7\b4\a7\fb\d4\05\53\25\d0\cd\29\88\00\56\25\24\7d\5d\b4\f3\41\9f\e9\b5\f7\ae\64\2c\e3\c9\6d\d5\84\3a\72\12\b8\7a\d9\1b\09\e8\38\da\26\4f\04\ce\03\71\6e\8a\44\7b\5c\81\59\9c\d2\e4\c3\ba\59\a6\e5\28\a7\8f\9a\e4\d5\4e\b9\ca\7f\cb\75\b8\2b\43\3e\b3\15\46\b1\a5\bc\9d\9e\38\15\f1\bd\1b\21\aa\f1\82\00\95\fc\a7\77\47\39\a7\33\43\92\d7\52\40\4b\06\81\8a\a0\bd\f1\6b\99\84\42\5b\e2\3b\c5\5e\12\5c\28\4d\b6\0e\4e\c8\5c\e8\01\8a\c5\e7\e4\9d\42\ee\5d\9c\c4\eb\eb\68\09\27\92\95\9a\11\54\73\c4\12\80\fb\7d\fe\c5\08\60\7f\36\41\e0\10\ba\d6\2b\6c\f1\b4\17\fe\26\34\e3\4b\f8\a8\e3\91\be\4f\2a\fc\da\81\b8\e7\fe\d5\26\50\47\f3\1a\65\32\81\e0\05\b8\4f\32\31\26\00\4a\53\97\c2\c3\0e\2e\a1\26\54\ab\05\8e\56\2f\7d\af\22\84\68\a5\8b\97\f6\a4\fd\a8\cc\75\41\96\86\fd\27\3d\29\86\8d\7f\4c\d4\8e\73\41\f4\1e\e2\dd\58\27\97\ce\9c\94\cf\7a\04\2f\dc\ed"
  1535    ))
  1536  
  1537    (func (export "f64.kahan_sum") (param $p i32) (param $n i32) (result f64)
  1538      (local $sum f64)
  1539      (local $c f64)
  1540      (local $t f64)
  1541      (block $exit
  1542        (loop $top
  1543          (local.set $t
  1544            (f64.sub
  1545              (f64.sub
  1546                (local.tee $sum
  1547                  (f64.add
  1548                    (local.get $c)
  1549                    (local.tee $t
  1550                      (f64.sub (f64.load (local.get $p)) (local.get $t))
  1551                    )
  1552                  )
  1553                )
  1554                (local.get $c)
  1555              )
  1556              (local.get $t)
  1557            )
  1558          )
  1559          (local.set $p (i32.add (local.get $p) (i32.const 8)))
  1560          (local.set $c (local.get $sum))
  1561          (br_if $top (local.tee $n (i32.add (local.get $n) (i32.const -1))))
  1562        )
  1563      )
  1564      (local.get $sum)
  1565    )
  1566  
  1567    (func (export "f64.plain_sum") (param $p i32) (param $n i32) (result f64)
  1568      (local $sum f64)
  1569      (block $exit
  1570        (loop $top
  1571          (local.set $sum (f64.add (local.get $sum) (f64.load (local.get $p))))
  1572          (local.set $p (i32.add (local.get $p) (i32.const 8)))
  1573          (local.set $n (i32.add (local.get $n) (i32.const -1)))
  1574          (br_if $top (local.get $n))
  1575        )
  1576      )
  1577      (local.get $sum)
  1578    )
  1579  )
  1580  
  1581  (assert_return (invoke "f64.kahan_sum" (i32.const 0) (i32.const 256)) (f64.const 0x1.dd7cb2a5ffc88p+998))
  1582  (assert_return (invoke "f64.plain_sum" (i32.const 0) (i32.const 256)) (f64.const 0x1.dd7cb2a63fc87p+998))
  1583  
  1584  ;; Test that -(x - y) is not folded to y - x.
  1585  
  1586  (module
  1587    (func (export "f32.no_fold_neg_sub") (param $x f32) (param $y f32) (result f32)
  1588      (f32.neg (f32.sub (local.get $x) (local.get $y))))
  1589  
  1590    (func (export "f64.no_fold_neg_sub") (param $x f64) (param $y f64) (result f64)
  1591      (f64.neg (f64.sub (local.get $x) (local.get $y))))
  1592  )
  1593  
  1594  (assert_return (invoke "f32.no_fold_neg_sub" (f32.const -0.0) (f32.const -0.0)) (f32.const -0.0))
  1595  (assert_return (invoke "f32.no_fold_neg_sub" (f32.const 0.0) (f32.const -0.0)) (f32.const -0.0))
  1596  (assert_return (invoke "f32.no_fold_neg_sub" (f32.const -0.0) (f32.const 0.0)) (f32.const 0.0))
  1597  (assert_return (invoke "f32.no_fold_neg_sub" (f32.const 0.0) (f32.const 0.0)) (f32.const -0.0))
  1598  
  1599  (assert_return (invoke "f64.no_fold_neg_sub" (f64.const -0.0) (f64.const -0.0)) (f64.const -0.0))
  1600  (assert_return (invoke "f64.no_fold_neg_sub" (f64.const 0.0) (f64.const -0.0)) (f64.const -0.0))
  1601  (assert_return (invoke "f64.no_fold_neg_sub" (f64.const -0.0) (f64.const 0.0)) (f64.const 0.0))
  1602  (assert_return (invoke "f64.no_fold_neg_sub" (f64.const 0.0) (f64.const 0.0)) (f64.const -0.0))
  1603  
  1604  ;; Test that -(x + y) is not folded to (-x + -y).
  1605  
  1606  (module
  1607    (func (export "f32.no_fold_neg_add") (param $x f32) (param $y f32) (result f32)
  1608      (f32.neg (f32.add (local.get $x) (local.get $y))))
  1609  
  1610    (func (export "f64.no_fold_neg_add") (param $x f64) (param $y f64) (result f64)
  1611      (f64.neg (f64.add (local.get $x) (local.get $y))))
  1612  )
  1613  
  1614  (assert_return (invoke "f32.no_fold_neg_add" (f32.const -0.0) (f32.const -0.0)) (f32.const 0.0))
  1615  (assert_return (invoke "f32.no_fold_neg_add" (f32.const 0.0) (f32.const -0.0)) (f32.const -0.0))
  1616  (assert_return (invoke "f32.no_fold_neg_add" (f32.const -0.0) (f32.const 0.0)) (f32.const -0.0))
  1617  (assert_return (invoke "f32.no_fold_neg_add" (f32.const 0.0) (f32.const 0.0)) (f32.const -0.0))
  1618  
  1619  (assert_return (invoke "f64.no_fold_neg_add" (f64.const -0.0) (f64.const -0.0)) (f64.const 0.0))
  1620  (assert_return (invoke "f64.no_fold_neg_add" (f64.const 0.0) (f64.const -0.0)) (f64.const -0.0))
  1621  (assert_return (invoke "f64.no_fold_neg_add" (f64.const -0.0) (f64.const 0.0)) (f64.const -0.0))
  1622  (assert_return (invoke "f64.no_fold_neg_add" (f64.const 0.0) (f64.const 0.0)) (f64.const -0.0))
  1623  
  1624  ;; Test that (-x + -y) is not folded to -(x + y).
  1625  
  1626  (module
  1627    (func (export "f32.no_fold_add_neg_neg") (param $x f32) (param $y f32) (result f32)
  1628      (f32.add (f32.neg (local.get $x)) (f32.neg (local.get $y))))
  1629  
  1630    (func (export "f64.no_fold_add_neg_neg") (param $x f64) (param $y f64) (result f64)
  1631      (f64.add (f64.neg (local.get $x)) (f64.neg (local.get $y))))
  1632  )
  1633  
  1634  (assert_return (invoke "f32.no_fold_add_neg_neg" (f32.const -0.0) (f32.const -0.0)) (f32.const 0.0))
  1635  (assert_return (invoke "f32.no_fold_add_neg_neg" (f32.const 0.0) (f32.const -0.0)) (f32.const 0.0))
  1636  (assert_return (invoke "f32.no_fold_add_neg_neg" (f32.const -0.0) (f32.const 0.0)) (f32.const 0.0))
  1637  (assert_return (invoke "f32.no_fold_add_neg_neg" (f32.const 0.0) (f32.const 0.0)) (f32.const -0.0))
  1638  
  1639  (assert_return (invoke "f64.no_fold_add_neg_neg" (f64.const -0.0) (f64.const -0.0)) (f64.const 0.0))
  1640  (assert_return (invoke "f64.no_fold_add_neg_neg" (f64.const 0.0) (f64.const -0.0)) (f64.const 0.0))
  1641  (assert_return (invoke "f64.no_fold_add_neg_neg" (f64.const -0.0) (f64.const 0.0)) (f64.const 0.0))
  1642  (assert_return (invoke "f64.no_fold_add_neg_neg" (f64.const 0.0) (f64.const 0.0)) (f64.const -0.0))
  1643  
  1644  ;; Test that -x + x is not folded to 0.0.
  1645  
  1646  (module
  1647    (func (export "f32.no_fold_add_neg") (param $x f32) (result f32)
  1648      (f32.add (f32.neg (local.get $x)) (local.get $x)))
  1649  
  1650    (func (export "f64.no_fold_add_neg") (param $x f64) (result f64)
  1651      (f64.add (f64.neg (local.get $x)) (local.get $x)))
  1652  )
  1653  
  1654  (assert_return (invoke "f32.no_fold_add_neg" (f32.const 0.0)) (f32.const 0.0))
  1655  (assert_return (invoke "f32.no_fold_add_neg" (f32.const -0.0)) (f32.const 0.0))
  1656  (assert_return (invoke "f32.no_fold_add_neg" (f32.const inf)) (f32.const nan:canonical))
  1657  (assert_return (invoke "f32.no_fold_add_neg" (f32.const -inf)) (f32.const nan:canonical))
  1658  
  1659  (assert_return (invoke "f64.no_fold_add_neg" (f64.const 0.0)) (f64.const 0.0))
  1660  (assert_return (invoke "f64.no_fold_add_neg" (f64.const -0.0)) (f64.const 0.0))
  1661  (assert_return (invoke "f64.no_fold_add_neg" (f64.const inf)) (f64.const nan:canonical))
  1662  (assert_return (invoke "f64.no_fold_add_neg" (f64.const -inf)) (f64.const nan:canonical))
  1663  
  1664  ;; Test that x+x+x+x+x+x is not folded to x * 6.
  1665  
  1666  (module
  1667    (func (export "f32.no_fold_6x_via_add") (param $x f32) (result f32)
  1668      (f32.add (f32.add (f32.add (f32.add (f32.add
  1669      (local.get $x)
  1670      (local.get $x)) (local.get $x)) (local.get $x))
  1671      (local.get $x)) (local.get $x)))
  1672  
  1673    (func (export "f64.no_fold_6x_via_add") (param $x f64) (result f64)
  1674      (f64.add (f64.add (f64.add (f64.add (f64.add
  1675      (local.get $x)
  1676      (local.get $x)) (local.get $x)) (local.get $x))
  1677      (local.get $x)) (local.get $x)))
  1678  )
  1679  
  1680  (assert_return (invoke "f32.no_fold_6x_via_add" (f32.const -0x1.598a0cp+99)) (f32.const -0x1.03278ap+102))
  1681  (assert_return (invoke "f32.no_fold_6x_via_add" (f32.const -0x1.d3e7acp-77)) (f32.const -0x1.5eedc2p-74))
  1682  (assert_return (invoke "f32.no_fold_6x_via_add" (f32.const 0x1.00fa02p-77)) (f32.const 0x1.817702p-75))
  1683  (assert_return (invoke "f32.no_fold_6x_via_add" (f32.const -0x1.51f434p-31)) (f32.const -0x1.faee4cp-29))
  1684  (assert_return (invoke "f32.no_fold_6x_via_add" (f32.const -0x1.00328ap+80)) (f32.const -0x1.804bcep+82))
  1685  
  1686  (assert_return (invoke "f64.no_fold_6x_via_add" (f64.const -0x1.310e15acaffe6p+68)) (f64.const -0x1.c995208307fdap+70))
  1687  (assert_return (invoke "f64.no_fold_6x_via_add" (f64.const -0x1.aad62c78fa9b4p-535)) (f64.const -0x1.4020a15abbf46p-532))
  1688  (assert_return (invoke "f64.no_fold_6x_via_add" (f64.const -0x1.f8fbfa94f6ab2p+271)) (f64.const -0x1.7abcfbefb9005p+274))
  1689  (assert_return (invoke "f64.no_fold_6x_via_add" (f64.const 0x1.756ccc2830a8ep+751)) (f64.const 0x1.1811991e247ebp+754))
  1690  (assert_return (invoke "f64.no_fold_6x_via_add" (f64.const -0x1.8fd1ab1d2402ap+234)) (f64.const -0x1.2bdd4055db01fp+237))
  1691  
  1692  ;; Test that (x/y)/z is not optimized to x/(y*z),
  1693  ;; which is an "allowable alternative Form" in Fortran.
  1694  
  1695  (module
  1696    (func (export "f32.no_fold_div_div") (param $x f32) (param $y f32) (param $z f32) (result f32)
  1697      (f32.div (f32.div (local.get $x) (local.get $y)) (local.get $z)))
  1698  
  1699    (func (export "f64.no_fold_div_div") (param $x f64) (param $y f64) (param $z f64) (result f64)
  1700      (f64.div (f64.div (local.get $x) (local.get $y)) (local.get $z)))
  1701  )
  1702  
  1703  (assert_return (invoke "f32.no_fold_div_div" (f32.const -0x1.f70228p+78) (f32.const -0x1.fbc612p-16) (f32.const -0x1.8c379p+10)) (f32.const -0x1.47b43cp+83))
  1704  (assert_return (invoke "f32.no_fold_div_div" (f32.const 0x1.d29d2ep-70) (f32.const 0x1.f3a17ep+110) (f32.const -0x1.64d41p-112)) (f32.const -0x0p+0))
  1705  (assert_return (invoke "f32.no_fold_div_div" (f32.const 0x1.867f98p+43) (f32.const 0x1.30acfcp-105) (f32.const 0x1.e210d8p+105)) (f32.const inf))
  1706  (assert_return (invoke "f32.no_fold_div_div" (f32.const -0x1.c4001ap-14) (f32.const -0x1.9beb6cp+124) (f32.const -0x1.74f34cp-43)) (f32.const -0x1.819874p-96))
  1707  (assert_return (invoke "f32.no_fold_div_div" (f32.const 0x1.db0e6ep+46) (f32.const 0x1.55eea2p+56) (f32.const -0x1.f3134p+124)) (f32.const -0x1.6cep-135))
  1708  
  1709  (assert_return (invoke "f64.no_fold_div_div" (f64.const 0x1.b4dc8ec3c7777p+337) (f64.const 0x1.9f95ac2d1863p+584) (f64.const -0x1.d4318abba341ep-782)) (f64.const -0x1.2649159d87e02p+534))
  1710  (assert_return (invoke "f64.no_fold_div_div" (f64.const -0x1.ac53af5eb445fp+791) (f64.const 0x1.8549c0a4ceb13p-29) (f64.const 0x1.64e384003c801p+316)) (f64.const -0x1.9417cdccbae91p+503))
  1711  (assert_return (invoke "f64.no_fold_div_div" (f64.const -0x1.d2685afb27327p+2) (f64.const -0x1.abb1eeed3dbebp+880) (f64.const 0x1.a543e2e6968a3p+170)) (f64.const 0x0.0000002a69a5fp-1022))
  1712  (assert_return (invoke "f64.no_fold_div_div" (f64.const -0x1.47ddede78ad1cp+825) (f64.const 0x1.6d932d070a367p-821) (f64.const 0x1.79cf18cc64fp+961)) (f64.const -inf))
  1713  (assert_return (invoke "f64.no_fold_div_div" (f64.const -0x1.f73d4979a9379p-888) (f64.const 0x1.4d83b53e97788p-596) (f64.const -0x1.f8f86c9603b5bp-139)) (f64.const 0x1.87a7bd89c586cp-154))
  1714  
  1715  ;; Test that (x/y)*(z/w) is not optimized to (x*z)/(y*w), example from
  1716  ;; http://perso.ens-lyon.fr/jean-michel.muller/Handbook.html
  1717  ;; section 7.4.1: FORTRAN Floating Point in a Nutshell: Philosophy
  1718  
  1719  (module
  1720    (func (export "f32.no_fold_mul_divs") (param $x f32) (param $y f32) (param $z f32) (param $w f32) (result f32)
  1721      (f32.mul (f32.div (local.get $x) (local.get $y)) (f32.div (local.get $z) (local.get $w))))
  1722  
  1723    (func (export "f64.no_fold_mul_divs") (param $x f64) (param $y f64) (param $z f64) (param $w f64) (result f64)
  1724      (f64.mul (f64.div (local.get $x) (local.get $y)) (f64.div (local.get $z) (local.get $w))))
  1725  )
  1726  
  1727  (assert_return (invoke "f32.no_fold_mul_divs" (f32.const -0x1.c483bep-109) (f32.const 0x1.ee1c3cp-92) (f32.const 0x1.800756p-88) (f32.const -0x1.95b972p+4)) (f32.const 0x1.bbd30cp-110))
  1728  (assert_return (invoke "f32.no_fold_mul_divs" (f32.const -0x1.0f4262p+102) (f32.const 0x1.248498p+25) (f32.const 0x1.f66a7cp-17) (f32.const 0x1.897fc8p-3)) (f32.const -0x1.2f1aa4p+63))
  1729  (assert_return (invoke "f32.no_fold_mul_divs" (f32.const -0x1.df5f22p+33) (f32.const -0x1.fcee3ep+39) (f32.const -0x1.9ea914p+29) (f32.const -0x1.2c4d3p+10)) (f32.const 0x1.4cf51cp+13))
  1730  (assert_return (invoke "f32.no_fold_mul_divs" (f32.const -0x1.f568bcp+109) (f32.const 0x1.d9963p-34) (f32.const 0x1.37a87ap-16) (f32.const 0x1.a1524ap+78)) (f32.const -inf))
  1731  (assert_return (invoke "f32.no_fold_mul_divs" (f32.const 0x1.3dd592p-53) (f32.const -0x1.332c22p-64) (f32.const 0x1.b01064p-91) (f32.const 0x1.92bb3ap-36)) (f32.const -0x1.1c2dbp-44))
  1732  
  1733  (assert_return (invoke "f64.no_fold_mul_divs" (f64.const -0x1.363d6764f7b12p-819) (f64.const -0x1.ed5471f660b5fp-464) (f64.const -0x1.671b0a7f3a42p+547) (f64.const 0x1.0633be34ba1f2p+186)) (f64.const -0x1.b8fa2b76baeebp+5))
  1734  (assert_return (invoke "f64.no_fold_mul_divs" (f64.const -0x1.37880182e0fa8p+115) (f64.const 0x1.f842631576147p-920) (f64.const -0x1.999372231d156p+362) (f64.const -0x1.d5db481ab9554p+467)) (f64.const -inf))
  1735  (assert_return (invoke "f64.no_fold_mul_divs" (f64.const -0x1.9a747c8d4b541p+308) (f64.const -0x1.99092ad6bbdc8p+192) (f64.const -0x1.cb23755c20101p-140) (f64.const -0x1.de8716f6b0b6ap+732)) (f64.const 0x1.ecf584c8466a5p-757))
  1736  (assert_return (invoke "f64.no_fold_mul_divs" (f64.const -0x1.c424b2ece903dp+129) (f64.const -0x1.568ce281db37fp-347) (f64.const 0x1.53900b99fd3dp-957) (f64.const 0x1.5c33952254dadp+223)) (f64.const 0x0p+0))
  1737  (assert_return (invoke "f64.no_fold_mul_divs" (f64.const 0x1.a8ec2cecb32a9p-18) (f64.const 0x1.58acab0051851p-277) (f64.const 0x1.35e87c9077f7fp-620) (f64.const -0x1.925ee37ffb386p+352)) (f64.const -0x1.e6286970b31bfp-714))
  1738  
  1739  ;; Test that (x/z)+(y/z) is not optimized to (x+y)/z.
  1740  
  1741  (module
  1742    (func (export "f32.no_fold_add_divs") (param $x f32) (param $y f32) (param $z f32) (result f32)
  1743      (f32.add (f32.div (local.get $x) (local.get $z)) (f32.div (local.get $y) (local.get $z))))
  1744  
  1745    (func (export "f64.no_fold_add_divs") (param $x f64) (param $y f64) (param $z f64) (result f64)
  1746      (f64.add (f64.div (local.get $x) (local.get $z)) (f64.div (local.get $y) (local.get $z))))
  1747  )
  1748  
  1749  (assert_return (invoke "f32.no_fold_add_divs" (f32.const 0x1.795e7p+8) (f32.const -0x1.48a5eep-5) (f32.const -0x1.9a244cp+126)) (f32.const -0x1.d709b6p-119))
  1750  (assert_return (invoke "f32.no_fold_add_divs" (f32.const -0x1.ae89e8p-63) (f32.const -0x1.e9903ep-49) (f32.const -0x1.370a8cp+47)) (f32.const 0x1.92f3f6p-96))
  1751  (assert_return (invoke "f32.no_fold_add_divs" (f32.const -0x1.626408p-46) (f32.const 0x1.2ee5b2p-64) (f32.const -0x1.ecefaap+48)) (f32.const 0x1.701864p-95))
  1752  (assert_return (invoke "f32.no_fold_add_divs" (f32.const -0x1.061d3p-101) (f32.const 0x1.383492p-98) (f32.const -0x1.1d92d2p+88)) (f32.const 0x0p+0))
  1753  (assert_return (invoke "f32.no_fold_add_divs" (f32.const 0x1.1ea39ep-10) (f32.const 0x1.a7fffep-3) (f32.const 0x1.6fc574p-123)) (f32.const 0x1.28b2dep+120))
  1754  
  1755  (assert_return (invoke "f64.no_fold_add_divs" (f64.const -0x1.c5fcc3273b136p+430) (f64.const 0x1.892a09eed8f6fp+434) (f64.const 0x1.8258b71e64397p+911)) (f64.const 0x1.e36eb9706ad82p-478))
  1756  (assert_return (invoke "f64.no_fold_add_divs" (f64.const -0x1.2215d4061b5b3p+53) (f64.const 0x1.fb6184d97f27cp+5) (f64.const -0x1.f3bb59dacc0ebp-957)) (f64.const 0x1.2934eb0118be3p+1009))
  1757  (assert_return (invoke "f64.no_fold_add_divs" (f64.const -0x1.e7a4533741d8ep-967) (f64.const 0x1.a519bb7feb802p-976) (f64.const 0x1.1f8a43454e51ap+504)) (f64.const 0x0p+0))
  1758  (assert_return (invoke "f64.no_fold_add_divs" (f64.const 0x1.991c6cf93e2b4p+313) (f64.const -0x1.f2f7432698d11p+329) (f64.const 0x1.0d8c1b2453617p-126)) (f64.const -0x1.d9e1d84ddd1d4p+455))
  1759  (assert_return (invoke "f64.no_fold_add_divs" (f64.const -0x1.d436849dc1271p-728) (f64.const 0x1.19d1c1450e52dp-755) (f64.const 0x1.fa1be69ea06fep-70)) (f64.const -0x1.d9a9b1c2f5623p-659))
  1760  
  1761  ;; Test that sqrt(x*x) is not optimized to abs(x).
  1762  
  1763  (module
  1764    (func (export "f32.no_fold_sqrt_square") (param $x f32) (result f32)
  1765      (f32.sqrt (f32.mul (local.get $x) (local.get $x))))
  1766  
  1767    (func (export "f64.no_fold_sqrt_square") (param $x f64) (result f64)
  1768      (f64.sqrt (f64.mul (local.get $x) (local.get $x))))
  1769  )
  1770  
  1771  (assert_return (invoke "f32.no_fold_sqrt_square" (f32.const -0x1.5cb316p-66)) (f32.const 0x1.5cb322p-66))
  1772  (assert_return (invoke "f32.no_fold_sqrt_square" (f32.const -0x1.b0f9e4p-73)) (f32.const 0x1.b211b2p-73))
  1773  (assert_return (invoke "f32.no_fold_sqrt_square" (f32.const -0x1.de417cp-71)) (f32.const 0x1.de65b8p-71))
  1774  (assert_return (invoke "f32.no_fold_sqrt_square" (f32.const 0x1.64c872p-86)) (f32.const 0x0p+0))
  1775  (assert_return (invoke "f32.no_fold_sqrt_square" (f32.const 0x1.e199e4p+108)) (f32.const inf))
  1776  
  1777  (assert_return (invoke "f64.no_fold_sqrt_square" (f64.const 0x1.1759d657203fdp-529)) (f64.const 0x1.1759dd57545f3p-529))
  1778  (assert_return (invoke "f64.no_fold_sqrt_square" (f64.const -0x1.4c68de1c78d83p-514)) (f64.const 0x1.4c68de1c78d81p-514))
  1779  (assert_return (invoke "f64.no_fold_sqrt_square" (f64.const -0x1.214736edb6e1ep-521)) (f64.const 0x1.214736ed9cf8dp-521))
  1780  (assert_return (invoke "f64.no_fold_sqrt_square" (f64.const -0x1.0864b9f68457p-616)) (f64.const 0x0p+0))
  1781  (assert_return (invoke "f64.no_fold_sqrt_square" (f64.const 0x1.b2a9855995abap+856)) (f64.const inf))
  1782  
  1783  ;; Test that sqrt(x)*sqrt(y) is not optimized to sqrt(x*y).
  1784  
  1785  (module
  1786    (func (export "f32.no_fold_mul_sqrts") (param $x f32) (param $y f32) (result f32)
  1787      (f32.mul (f32.sqrt (local.get $x)) (f32.sqrt (local.get $y))))
  1788  
  1789    (func (export "f64.no_fold_mul_sqrts") (param $x f64) (param $y f64) (result f64)
  1790      (f64.mul (f64.sqrt (local.get $x)) (f64.sqrt (local.get $y))))
  1791  )
  1792  
  1793  (assert_return (invoke "f32.no_fold_mul_sqrts" (f32.const 0x1.dddda8p-125) (f32.const -0x1.25d22ap-83)) (f32.const nan:canonical))
  1794  (assert_return (invoke "f32.no_fold_mul_sqrts" (f32.const 0x1.418d14p-92) (f32.const 0x1.c6535cp-32)) (f32.const 0x1.7e373ap-62))
  1795  (assert_return (invoke "f32.no_fold_mul_sqrts" (f32.const 0x1.4de7ep-88) (f32.const 0x1.84ff18p+6)) (f32.const 0x1.686668p-41))
  1796  (assert_return (invoke "f32.no_fold_mul_sqrts" (f32.const 0x1.78091ep+101) (f32.const 0x1.81feb8p-9)) (f32.const 0x1.7cfb98p+46))
  1797  (assert_return (invoke "f32.no_fold_mul_sqrts" (f32.const 0x1.583ap-56) (f32.const 0x1.14ba2ap-9)) (f32.const 0x1.b47a8ep-33))
  1798  
  1799  (assert_return (invoke "f64.no_fold_mul_sqrts" (f64.const -0x1.d1144cc28cdbep-635) (f64.const -0x1.bf9bc373d3b6ap-8)) (f64.const nan:canonical))
  1800  (assert_return (invoke "f64.no_fold_mul_sqrts" (f64.const 0x1.5a7eb976bebc9p-643) (f64.const 0x1.f30cb8865a4cap-404)) (f64.const 0x1.260a1032d6e76p-523))
  1801  (assert_return (invoke "f64.no_fold_mul_sqrts" (f64.const 0x1.711a0c1707935p-89) (f64.const 0x1.6fb5de51a20d3p-913)) (f64.const 0x1.7067ca28e31ecp-501))
  1802  (assert_return (invoke "f64.no_fold_mul_sqrts" (f64.const 0x1.fb0bbea33b076p-363) (f64.const 0x1.d963b34894158p-573)) (f64.const 0x1.e9edc1fa624afp-468))
  1803  (assert_return (invoke "f64.no_fold_mul_sqrts" (f64.const 0x1.8676eab7a4d0dp+24) (f64.const 0x1.75a58231ba7a5p+513)) (f64.const 0x1.0e16aebe203b3p+269))
  1804  
  1805  ;; Test that sqrt(x)/sqrt(y) is not optimized to sqrt(x/y).
  1806  
  1807  (module
  1808    (func (export "f32.no_fold_div_sqrts") (param $x f32) (param $y f32) (result f32)
  1809      (f32.div (f32.sqrt (local.get $x)) (f32.sqrt (local.get $y))))
  1810  
  1811    (func (export "f64.no_fold_div_sqrts") (param $x f64) (param $y f64) (result f64)
  1812      (f64.div (f64.sqrt (local.get $x)) (f64.sqrt (local.get $y))))
  1813  )
  1814  
  1815  (assert_return (invoke "f32.no_fold_div_sqrts" (f32.const -0x1.bea9bap+25) (f32.const -0x1.db776ep-58)) (f32.const nan:canonical))
  1816  (assert_return (invoke "f32.no_fold_div_sqrts" (f32.const 0x1.b983b6p+32) (f32.const 0x1.901f1ep+27)) (f32.const 0x1.7c4df6p+2))
  1817  (assert_return (invoke "f32.no_fold_div_sqrts" (f32.const 0x1.d45e72p-120) (f32.const 0x1.ab49ccp+15)) (f32.const 0x1.7b0b04p-68))
  1818  (assert_return (invoke "f32.no_fold_div_sqrts" (f32.const 0x1.b2e444p+59) (f32.const 0x1.5b8b16p-30)) (f32.const 0x1.94fca8p+44))
  1819  (assert_return (invoke "f32.no_fold_div_sqrts" (f32.const 0x1.835aa6p-112) (f32.const 0x1.d17128p-103)) (f32.const 0x1.4a468p-5))
  1820  
  1821  (assert_return (invoke "f64.no_fold_div_sqrts" (f64.const -0x1.509fc16411167p-711) (f64.const -0x1.9c4255f5d6517p-187)) (f64.const nan:canonical))
  1822  (assert_return (invoke "f64.no_fold_div_sqrts" (f64.const 0x1.b6897bddac76p-587) (f64.const 0x1.104578b4c91f3p+541)) (f64.const 0x1.44e4f21f26cc9p-564))
  1823  (assert_return (invoke "f64.no_fold_div_sqrts" (f64.const 0x1.ac83451b08989p+523) (f64.const 0x1.8da575c6d12b8p-109)) (f64.const 0x1.09c003991ce17p+316))
  1824  (assert_return (invoke "f64.no_fold_div_sqrts" (f64.const 0x1.bab7836456417p-810) (f64.const 0x1.1ff60d03ba607p+291)) (f64.const 0x1.c0e6c833bf657p-551))
  1825  (assert_return (invoke "f64.no_fold_div_sqrts" (f64.const 0x1.a957816ad9515p-789) (f64.const 0x1.8c18a3a222ab1p+945)) (f64.const 0x1.0948539781e92p-867))
  1826  
  1827  ;; Test that (x*sqrt(y))/y is not optimized to x/sqrt(y).
  1828  
  1829  (module
  1830    (func (export "f32.no_fold_mul_sqrt_div") (param $x f32) (param $y f32) (result f32)
  1831      (f32.div (f32.mul (local.get $x) (f32.sqrt (local.get $y))) (local.get $y)))
  1832  
  1833    (func (export "f64.no_fold_mul_sqrt_div") (param $x f64) (param $y f64) (result f64)
  1834      (f64.div (f64.mul (local.get $x) (f64.sqrt (local.get $y))) (local.get $y)))
  1835  )
  1836  
  1837  (assert_return (invoke "f32.no_fold_mul_sqrt_div" (f32.const -0x1.f4a7cap+81) (f32.const 0x1.c09adep+92)) (f32.const -inf))
  1838  (assert_return (invoke "f32.no_fold_mul_sqrt_div" (f32.const -0x1.90bf1cp-120) (f32.const 0x1.8dbe88p-97)) (f32.const -0x0p+0))
  1839  (assert_return (invoke "f32.no_fold_mul_sqrt_div" (f32.const 0x1.8570e8p+29) (f32.const 0x1.217d3p-128)) (f32.const 0x1.6e391ap+93))
  1840  (assert_return (invoke "f32.no_fold_mul_sqrt_div" (f32.const -0x1.5b4652p+43) (f32.const 0x1.a9d71cp+112)) (f32.const -0x1.0d423ap-13))
  1841  (assert_return (invoke "f32.no_fold_mul_sqrt_div" (f32.const -0x1.910604p+8) (f32.const 0x1.0ca912p+7)) (f32.const -0x1.14cdecp+5))
  1842  
  1843  (assert_return (invoke "f64.no_fold_mul_sqrt_div" (f64.const 0x1.1dcdeb857305fp+698) (f64.const 0x1.a066171c40eb9p+758)) (f64.const inf))
  1844  (assert_return (invoke "f64.no_fold_mul_sqrt_div" (f64.const -0x1.8b4f1c218e2abp-827) (f64.const 0x1.5e1ee65953b0bp-669)) (f64.const -0x0p+0))
  1845  (assert_return (invoke "f64.no_fold_mul_sqrt_div" (f64.const 0x1.74ee531ddba38p-425) (f64.const 0x1.f370f758857f3p+560)) (f64.const 0x1.0aff34269583ep-705))
  1846  (assert_return (invoke "f64.no_fold_mul_sqrt_div" (f64.const -0x1.27f216b0da6c5p+352) (f64.const 0x1.8e0b4e0b9fd7ep-483)) (f64.const -0x1.4fa558aad514ep+593))
  1847  (assert_return (invoke "f64.no_fold_mul_sqrt_div" (f64.const 0x1.4c6955df9912bp+104) (f64.const 0x1.0cca42c9d371ep+842)) (f64.const 0x1.4468072f54294p-317))
  1848  
  1849  ;; Test that subnormals are not flushed even in an intermediate value in an
  1850  ;; expression with a normal result.
  1851  
  1852  (module
  1853    (func (export "f32.no_flush_intermediate_subnormal") (param $x f32) (param $y f32) (param $z f32) (result f32)
  1854      (f32.mul (f32.mul (local.get $x) (local.get $y)) (local.get $z)))
  1855  
  1856    (func (export "f64.no_flush_intermediate_subnormal") (param $x f64) (param $y f64) (param $z f64) (result f64)
  1857      (f64.mul (f64.mul (local.get $x) (local.get $y)) (local.get $z)))
  1858  )
  1859  
  1860  (assert_return (invoke "f32.no_flush_intermediate_subnormal" (f32.const 0x1p-126) (f32.const 0x1p-23) (f32.const 0x1p23)) (f32.const 0x1p-126))
  1861  (assert_return (invoke "f64.no_flush_intermediate_subnormal" (f64.const 0x1p-1022) (f64.const 0x1p-52) (f64.const 0x1p52)) (f64.const 0x1p-1022))
  1862  
  1863  ;; Test corner cases of John Hauser's microarchitectural recoding scheme.
  1864  ;; https://github.com/riscv/riscv-tests/blob/695b86a6fcbe06ffbed8891af7e6fe7bf2062543/isa/rv64uf/recoding.S
  1865  
  1866  (module
  1867    (func (export "f32.recoding_eq") (param $x f32) (param $y f32) (result i32)
  1868      (f32.eq (f32.mul (local.get $x) (local.get $y)) (local.get $x)))
  1869  
  1870    (func (export "f32.recoding_le") (param $x f32) (param $y f32) (result i32)
  1871      (f32.le (f32.mul (local.get $x) (local.get $y)) (local.get $x)))
  1872  
  1873    (func (export "f32.recoding_lt") (param $x f32) (param $y f32) (result i32)
  1874      (f32.lt (f32.mul (local.get $x) (local.get $y)) (local.get $x)))
  1875  
  1876    (func (export "f64.recoding_eq") (param $x f64) (param $y f64) (result i32)
  1877      (f64.eq (f64.mul (local.get $x) (local.get $y)) (local.get $x)))
  1878  
  1879    (func (export "f64.recoding_le") (param $x f64) (param $y f64) (result i32)
  1880      (f64.le (f64.mul (local.get $x) (local.get $y)) (local.get $x)))
  1881  
  1882    (func (export "f64.recoding_lt") (param $x f64) (param $y f64) (result i32)
  1883      (f64.lt (f64.mul (local.get $x) (local.get $y)) (local.get $x)))
  1884  
  1885    (func (export "recoding_demote") (param $x f64) (param $y f32) (result f32)
  1886      (f32.mul (f32.demote_f64 (local.get $x)) (local.get $y)))
  1887  )
  1888  
  1889  (assert_return (invoke "f32.recoding_eq" (f32.const -inf) (f32.const 3.0)) (i32.const 1))
  1890  (assert_return (invoke "f32.recoding_le" (f32.const -inf) (f32.const 3.0)) (i32.const 1))
  1891  (assert_return (invoke "f32.recoding_lt" (f32.const -inf) (f32.const 3.0)) (i32.const 0))
  1892  
  1893  (assert_return (invoke "f32.recoding_eq" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 1))
  1894  (assert_return (invoke "f32.recoding_le" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 1))
  1895  (assert_return (invoke "f32.recoding_lt" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 0))
  1896  
  1897  (assert_return (invoke "f64.recoding_eq" (f64.const -inf) (f64.const 3.0)) (i32.const 1))
  1898  (assert_return (invoke "f64.recoding_le" (f64.const -inf) (f64.const 3.0)) (i32.const 1))
  1899  (assert_return (invoke "f64.recoding_lt" (f64.const -inf) (f64.const 3.0)) (i32.const 0))
  1900  
  1901  (assert_return (invoke "f64.recoding_eq" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 1))
  1902  (assert_return (invoke "f64.recoding_le" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 1))
  1903  (assert_return (invoke "f64.recoding_lt" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 0))
  1904  
  1905  (assert_return (invoke "recoding_demote" (f64.const 0x1.4c8f8p-132) (f32.const 1221)) (f32.const 0x1.8c8a1cp-122))
  1906  
  1907  ;; Test that division is not done as on an extended-base system.
  1908  ;; http://www.ucbtest.org/goldberg/addendum.html
  1909  
  1910  (module
  1911    (func (export "f32.no_extended_precision_div") (param $x f32) (param $y f32) (param $z f32) (result i32)
  1912      (f32.eq (f32.div (local.get $x) (local.get $y)) (local.get $z)))
  1913  
  1914    (func (export "f64.no_extended_precision_div") (param $x f64) (param $y f64) (param $z f64) (result i32)
  1915      (f64.eq (f64.div (local.get $x) (local.get $y)) (local.get $z)))
  1916  )
  1917  
  1918  (assert_return (invoke "f32.no_extended_precision_div" (f32.const 3.0) (f32.const 7.0) (f32.const 0x1.b6db6ep-2)) (i32.const 1))
  1919  (assert_return (invoke "f64.no_extended_precision_div" (f64.const 3.0) (f64.const 7.0) (f64.const 0x1.b6db6db6db6dbp-2)) (i32.const 1))
  1920  
  1921  ;; a*x + b*x == (a+b)*x for all x only if the operations a*x, b*x, and (a+b)
  1922  ;; are all exact operations, which is true only if a and b are exact powers of
  1923  ;; 2. Even then, if a==-b and x==-0, then a*x+b*x==0.0, (a+b)*x==-0.0.
  1924  ;; https://dlang.org/d-floating-point.html
  1925  
  1926  (module
  1927    (func (export "f32.no_distribute_exact") (param $x f32) (result f32)
  1928      (f32.add (f32.mul (f32.const -8.0) (local.get $x)) (f32.mul (f32.const 8.0) (local.get $x))))
  1929  
  1930    (func (export "f64.no_distribute_exact") (param $x f64) (result f64)
  1931      (f64.add (f64.mul (f64.const -8.0) (local.get $x)) (f64.mul (f64.const 8.0) (local.get $x))))
  1932  )
  1933  
  1934  (assert_return (invoke "f32.no_distribute_exact" (f32.const -0.0)) (f32.const 0.0))
  1935  (assert_return (invoke "f64.no_distribute_exact" (f64.const -0.0)) (f64.const 0.0))
  1936  
  1937  ;; Test that various approximations of sqrt(2), sqrt(3), and sqrt(5) compute the
  1938  ;; expected approximation.
  1939  ;; https://xkcd.com/1047/
  1940  (module
  1941    (func (export "f32.sqrt") (param f32) (result f32)
  1942      (f32.sqrt (local.get 0)))
  1943  
  1944    (func (export "f32.xkcd_sqrt_2") (param f32) (param f32) (param f32) (param f32) (result f32)
  1945      (f32.add (f32.div (local.get 0) (local.get 1)) (f32.div (local.get 2) (f32.sub (local.get 3) (local.get 2)))))
  1946  
  1947    (func (export "f32.xkcd_sqrt_3") (param f32) (param f32) (param f32) (result f32)
  1948      (f32.div (f32.mul (local.get 0) (local.get 1)) (local.get 2)))
  1949  
  1950    (func (export "f32.xkcd_sqrt_5") (param f32) (param f32) (param f32) (result f32)
  1951      (f32.add (f32.div (local.get 0) (local.get 1)) (f32.div (local.get 2) (local.get 0))))
  1952  
  1953    (func (export "f32.xkcd_better_sqrt_5") (param f32) (param f32) (param f32) (param f32) (result f32)
  1954      (f32.div (f32.add (local.get 0) (f32.mul (local.get 1) (local.get 2))) (f32.sub (local.get 3) (f32.mul (local.get 1) (local.get 2)))))
  1955  
  1956    (func (export "f64.sqrt") (param f64) (result f64)
  1957      (f64.sqrt (local.get 0)))
  1958  
  1959    (func (export "f64.xkcd_sqrt_2") (param f64) (param f64) (param f64) (param f64) (result f64)
  1960      (f64.add (f64.div (local.get 0) (local.get 1)) (f64.div (local.get 2) (f64.sub (local.get 3) (local.get 2)))))
  1961  
  1962    (func (export "f64.xkcd_sqrt_3") (param f64) (param f64) (param f64) (result f64)
  1963      (f64.div (f64.mul (local.get 0) (local.get 1)) (local.get 2)))
  1964  
  1965    (func (export "f64.xkcd_sqrt_5") (param f64) (param f64) (param f64) (result f64)
  1966      (f64.add (f64.div (local.get 0) (local.get 1)) (f64.div (local.get 2) (local.get 0))))
  1967  
  1968    (func (export "f64.xkcd_better_sqrt_5") (param f64) (param f64) (param f64) (param f64) (result f64)
  1969      (f64.div (f64.add (local.get 0) (f64.mul (local.get 1) (local.get 2))) (f64.sub (local.get 3) (f64.mul (local.get 1) (local.get 2)))))
  1970  )
  1971  
  1972  (assert_return (invoke "f32.sqrt" (f32.const 2.0)) (f32.const 0x1.6a09e6p+0))
  1973  (assert_return (invoke "f32.xkcd_sqrt_2" (f32.const 3.0) (f32.const 5.0) (f32.const 0x1.921fb6p+1) (f32.const 7.0)) (f32.const 0x1.6a0a54p+0))
  1974  (assert_return (invoke "f32.sqrt" (f32.const 3.0)) (f32.const 0x1.bb67aep+0))
  1975  (assert_return (invoke "f32.xkcd_sqrt_3" (f32.const 2.0) (f32.const 0x1.5bf0a8p+1) (f32.const 0x1.921fb6p+1)) (f32.const 0x1.bb02d4p+0))
  1976  (assert_return (invoke "f32.sqrt" (f32.const 5.0)) (f32.const 0x1.1e377ap+1))
  1977  (assert_return (invoke "f32.xkcd_sqrt_5" (f32.const 2.0) (f32.const 0x1.5bf0a8p+1) (f32.const 3.0)) (f32.const 0x1.1e2d58p+1))
  1978  (assert_return (invoke "f32.xkcd_better_sqrt_5" (f32.const 13.0) (f32.const 4.0) (f32.const 0x1.921fb6p+1) (f32.const 24.0)) (f32.const 0x1.1e377ap+1))
  1979  
  1980  (assert_return (invoke "f64.sqrt" (f64.const 2.0)) (f64.const 0x1.6a09e667f3bcdp+0))
  1981  (assert_return (invoke "f64.xkcd_sqrt_2" (f64.const 3.0) (f64.const 5.0) (f64.const 0x1.921fb54442d18p+1) (f64.const 7.0)) (f64.const 0x1.6a0a5362b055fp+0))
  1982  (assert_return (invoke "f64.sqrt" (f64.const 3.0)) (f64.const 0x1.bb67ae8584caap+0))
  1983  (assert_return (invoke "f64.xkcd_sqrt_3" (f64.const 2.0) (f64.const 0x1.5bf0a8b145769p+1) (f64.const 0x1.921fb54442d18p+1)) (f64.const 0x1.bb02d4eca8f95p+0))
  1984  (assert_return (invoke "f64.sqrt" (f64.const 5.0)) (f64.const 0x1.1e3779b97f4a8p+1))
  1985  (assert_return (invoke "f64.xkcd_sqrt_5" (f64.const 2.0) (f64.const 0x1.5bf0a8b145769p+1) (f64.const 3.0)) (f64.const 0x1.1e2d58d8b3bcep+1))
  1986  (assert_return (invoke "f64.xkcd_better_sqrt_5" (f64.const 13.0) (f64.const 4.0) (f64.const 0x1.921fb54442d18p+1) (f64.const 24.0)) (f64.const 0x1.1e3778509a5a3p+1))
  1987  
  1988  ;; Compute the floating-point radix.
  1989  ;; M. A. Malcom. Algorithms to reveal properties of floating-point arithmetic.
  1990  ;; Communications of the ACM, 15(11):949-951, November 1972.
  1991  (module
  1992    (func (export "f32.compute_radix") (param $0 f32) (param $1 f32) (result f32)
  1993      (loop $label$0
  1994        (br_if $label$0
  1995          (f32.eq
  1996            (f32.add
  1997              (f32.sub
  1998                (f32.add
  1999                  (local.tee $0 (f32.add (local.get $0) (local.get $0)))
  2000                  (f32.const 1)
  2001                )
  2002                (local.get $0)
  2003              )
  2004              (f32.const -1)
  2005            )
  2006            (f32.const 0)
  2007          )
  2008        )
  2009      )
  2010      (loop $label$2
  2011        (br_if $label$2
  2012          (f32.ne
  2013            (f32.sub
  2014              (f32.sub
  2015                (f32.add
  2016                  (local.get $0)
  2017                  (local.tee $1 (f32.add (local.get $1) (f32.const 1)))
  2018                )
  2019                (local.get $0)
  2020              )
  2021              (local.get $1)
  2022            )
  2023            (f32.const 0)
  2024          )
  2025        )
  2026      )
  2027      (local.get $1)
  2028    )
  2029  
  2030    (func (export "f64.compute_radix") (param $0 f64) (param $1 f64) (result f64)
  2031      (loop $label$0
  2032        (br_if $label$0
  2033          (f64.eq
  2034            (f64.add
  2035              (f64.sub
  2036                (f64.add
  2037                  (local.tee $0 (f64.add (local.get $0) (local.get $0)))
  2038                  (f64.const 1)
  2039                )
  2040                (local.get $0)
  2041              )
  2042              (f64.const -1)
  2043            )
  2044            (f64.const 0)
  2045          )
  2046        )
  2047      )
  2048      (loop $label$2
  2049        (br_if $label$2
  2050          (f64.ne
  2051            (f64.sub
  2052              (f64.sub
  2053                (f64.add
  2054                  (local.get $0)
  2055                  (local.tee $1 (f64.add (local.get $1) (f64.const 1)))
  2056                )
  2057                (local.get $0)
  2058              )
  2059              (local.get $1)
  2060            )
  2061            (f64.const 0)
  2062          )
  2063        )
  2064      )
  2065      (local.get $1)
  2066    )
  2067  )
  2068  
  2069  (assert_return (invoke "f32.compute_radix" (f32.const 1.0) (f32.const 1.0)) (f32.const 2.0))
  2070  (assert_return (invoke "f64.compute_radix" (f64.const 1.0) (f64.const 1.0)) (f64.const 2.0))
  2071  
  2072  ;; Test that (x - 1) * y + y is not optimized to x * y.
  2073  ;; http://blog.frama-c.com/index.php?post/2013/05/14/Contrarianism
  2074  
  2075  (module
  2076    (func (export "f32.no_fold_sub1_mul_add") (param $x f32) (param $y f32) (result f32)
  2077      (f32.add (f32.mul (f32.sub (local.get $x) (f32.const 1.0)) (local.get $y)) (local.get $y)))
  2078  
  2079    (func (export "f64.no_fold_sub1_mul_add") (param $x f64) (param $y f64) (result f64)
  2080      (f64.add (f64.mul (f64.sub (local.get $x) (f64.const 1.0)) (local.get $y)) (local.get $y)))
  2081  )
  2082  
  2083  (assert_return (invoke "f32.no_fold_sub1_mul_add" (f32.const 0x1p-32) (f32.const 1.0)) (f32.const 0x0p+0))
  2084  (assert_return (invoke "f64.no_fold_sub1_mul_add" (f64.const 0x1p-64) (f64.const 1.0)) (f64.const 0x0p+0))
  2085  
  2086  ;; Test that x+z >= y+z is not optimized to x >= y (monotonicity).
  2087  ;; http://cs.nyu.edu/courses/spring13/CSCI-UA.0201-003/lecture6.pdf
  2088  
  2089  (module
  2090    (func (export "f32.no_fold_add_le_monotonicity") (param $x f32) (param $y f32) (param $z f32) (result i32)
  2091      (f32.le (f32.add (local.get $x) (local.get $z)) (f32.add (local.get $y) (local.get $z))))
  2092  
  2093    (func (export "f32.no_fold_add_ge_monotonicity") (param $x f32) (param $y f32) (param $z f32) (result i32)
  2094      (f32.ge (f32.add (local.get $x) (local.get $z)) (f32.add (local.get $y) (local.get $z))))
  2095  
  2096    (func (export "f64.no_fold_add_le_monotonicity") (param $x f64) (param $y f64) (param $z f64) (result i32)
  2097      (f64.le (f64.add (local.get $x) (local.get $z)) (f64.add (local.get $y) (local.get $z))))
  2098  
  2099    (func (export "f64.no_fold_add_ge_monotonicity") (param $x f64) (param $y f64) (param $z f64) (result i32)
  2100      (f64.ge (f64.add (local.get $x) (local.get $z)) (f64.add (local.get $y) (local.get $z))))
  2101  )
  2102  
  2103  (assert_return (invoke "f32.no_fold_add_le_monotonicity" (f32.const 0.0) (f32.const 0.0) (f32.const nan)) (i32.const 0))
  2104  (assert_return (invoke "f32.no_fold_add_le_monotonicity" (f32.const inf) (f32.const -inf) (f32.const inf)) (i32.const 0))
  2105  (assert_return (invoke "f64.no_fold_add_le_monotonicity" (f64.const 0.0) (f64.const 0.0) (f64.const nan)) (i32.const 0))
  2106  (assert_return (invoke "f64.no_fold_add_le_monotonicity" (f64.const inf) (f64.const -inf) (f64.const inf)) (i32.const 0))
  2107  
  2108  ;; Test that !(x < y) and friends are not optimized to x >= y and friends.
  2109  
  2110  (module
  2111    (func (export "f32.not_lt") (param $x f32) (param $y f32) (result i32)
  2112      (i32.eqz (f32.lt (local.get $x) (local.get $y))))
  2113  
  2114    (func (export "f32.not_le") (param $x f32) (param $y f32) (result i32)
  2115      (i32.eqz (f32.le (local.get $x) (local.get $y))))
  2116  
  2117    (func (export "f32.not_gt") (param $x f32) (param $y f32) (result i32)
  2118      (i32.eqz (f32.gt (local.get $x) (local.get $y))))
  2119  
  2120    (func (export "f32.not_ge") (param $x f32) (param $y f32) (result i32)
  2121      (i32.eqz (f32.ge (local.get $x) (local.get $y))))
  2122  
  2123    (func (export "f64.not_lt") (param $x f64) (param $y f64) (result i32)
  2124      (i32.eqz (f64.lt (local.get $x) (local.get $y))))
  2125  
  2126    (func (export "f64.not_le") (param $x f64) (param $y f64) (result i32)
  2127      (i32.eqz (f64.le (local.get $x) (local.get $y))))
  2128  
  2129    (func (export "f64.not_gt") (param $x f64) (param $y f64) (result i32)
  2130      (i32.eqz (f64.gt (local.get $x) (local.get $y))))
  2131  
  2132    (func (export "f64.not_ge") (param $x f64) (param $y f64) (result i32)
  2133      (i32.eqz (f64.ge (local.get $x) (local.get $y))))
  2134  )
  2135  
  2136  (assert_return (invoke "f32.not_lt" (f32.const nan) (f32.const 0.0)) (i32.const 1))
  2137  (assert_return (invoke "f32.not_le" (f32.const nan) (f32.const 0.0)) (i32.const 1))
  2138  (assert_return (invoke "f32.not_gt" (f32.const nan) (f32.const 0.0)) (i32.const 1))
  2139  (assert_return (invoke "f32.not_ge" (f32.const nan) (f32.const 0.0)) (i32.const 1))
  2140  (assert_return (invoke "f64.not_lt" (f64.const nan) (f64.const 0.0)) (i32.const 1))
  2141  (assert_return (invoke "f64.not_le" (f64.const nan) (f64.const 0.0)) (i32.const 1))
  2142  (assert_return (invoke "f64.not_gt" (f64.const nan) (f64.const 0.0)) (i32.const 1))
  2143  (assert_return (invoke "f64.not_ge" (f64.const nan) (f64.const 0.0)) (i32.const 1))
  2144  
  2145  ;; Test that a method for approximating a "machine epsilon" produces the expected
  2146  ;; approximation.
  2147  ;; http://blogs.mathworks.com/cleve/2014/07/07/floating-point-numbers/#24cb4f4d-b8a9-4c19-b22b-9d2a9f7f3812
  2148  
  2149  (module
  2150    (func (export "f32.epsilon") (result f32)
  2151      (f32.sub (f32.const 1.0) (f32.mul (f32.const 3.0) (f32.sub (f32.div (f32.const 4.0) (f32.const 3.0)) (f32.const 1.0)))))
  2152  
  2153    (func (export "f64.epsilon") (result f64)
  2154      (f64.sub (f64.const 1.0) (f64.mul (f64.const 3.0) (f64.sub (f64.div (f64.const 4.0) (f64.const 3.0)) (f64.const 1.0)))))
  2155  )
  2156  
  2157  (assert_return (invoke "f32.epsilon") (f32.const -0x1p-23))
  2158  (assert_return (invoke "f64.epsilon") (f64.const 0x1p-52))
  2159  
  2160  ;; Test that a method for computing a "machine epsilon" produces the expected
  2161  ;; result.
  2162  ;; https://www.math.utah.edu/~beebe/software/ieee/
  2163  
  2164  (module
  2165    (func (export "f32.epsilon") (result f32)
  2166      (local $x f32)
  2167      (local $result f32)
  2168      (local.set $x (f32.const 1))
  2169      (loop $loop
  2170        (br_if $loop
  2171          (f32.gt
  2172            (f32.add
  2173              (local.tee $x
  2174                (f32.mul
  2175                  (local.tee $result (local.get $x))
  2176                  (f32.const 0.5)
  2177                )
  2178              )
  2179              (f32.const 1)
  2180            )
  2181            (f32.const 1)
  2182          )
  2183        )
  2184      )
  2185      (local.get $result)
  2186    )
  2187  
  2188    (func (export "f64.epsilon") (result f64)
  2189      (local $x f64)
  2190      (local $result f64)
  2191      (local.set $x (f64.const 1))
  2192      (loop $loop
  2193        (br_if $loop
  2194          (f64.gt
  2195            (f64.add
  2196              (local.tee $x
  2197                (f64.mul
  2198                  (local.tee $result (local.get $x))
  2199                  (f64.const 0.5)
  2200                )
  2201              )
  2202              (f64.const 1)
  2203            )
  2204            (f64.const 1)
  2205          )
  2206        )
  2207      )
  2208      (local.get $result)
  2209    )
  2210  )
  2211  
  2212  (assert_return (invoke "f32.epsilon") (f32.const 0x1p-23))
  2213  (assert_return (invoke "f64.epsilon") (f64.const 0x1p-52))
  2214  
  2215  ;; Test that floating-point numbers are not optimized as if they form a
  2216  ;; trichotomy.
  2217  
  2218  (module
  2219    (func (export "f32.no_trichotomy_lt") (param $x f32) (param $y f32) (result i32)
  2220      (i32.or (f32.lt (local.get $x) (local.get $y)) (f32.ge (local.get $x) (local.get $y))))
  2221    (func (export "f32.no_trichotomy_le") (param $x f32) (param $y f32) (result i32)
  2222      (i32.or (f32.le (local.get $x) (local.get $y)) (f32.gt (local.get $x) (local.get $y))))
  2223    (func (export "f32.no_trichotomy_gt") (param $x f32) (param $y f32) (result i32)
  2224      (i32.or (f32.gt (local.get $x) (local.get $y)) (f32.le (local.get $x) (local.get $y))))
  2225    (func (export "f32.no_trichotomy_ge") (param $x f32) (param $y f32) (result i32)
  2226      (i32.or (f32.ge (local.get $x) (local.get $y)) (f32.lt (local.get $x) (local.get $y))))
  2227  
  2228    (func (export "f64.no_trichotomy_lt") (param $x f64) (param $y f64) (result i32)
  2229      (i32.or (f64.lt (local.get $x) (local.get $y)) (f64.ge (local.get $x) (local.get $y))))
  2230    (func (export "f64.no_trichotomy_le") (param $x f64) (param $y f64) (result i32)
  2231      (i32.or (f64.le (local.get $x) (local.get $y)) (f64.gt (local.get $x) (local.get $y))))
  2232    (func (export "f64.no_trichotomy_gt") (param $x f64) (param $y f64) (result i32)
  2233      (i32.or (f64.gt (local.get $x) (local.get $y)) (f64.le (local.get $x) (local.get $y))))
  2234    (func (export "f64.no_trichotomy_ge") (param $x f64) (param $y f64) (result i32)
  2235      (i32.or (f64.ge (local.get $x) (local.get $y)) (f64.lt (local.get $x) (local.get $y))))
  2236  )
  2237  
  2238  (assert_return (invoke "f32.no_trichotomy_lt" (f32.const 0.0) (f32.const nan)) (i32.const 0))
  2239  (assert_return (invoke "f32.no_trichotomy_le" (f32.const 0.0) (f32.const nan)) (i32.const 0))
  2240  (assert_return (invoke "f32.no_trichotomy_gt" (f32.const 0.0) (f32.const nan)) (i32.const 0))
  2241  (assert_return (invoke "f32.no_trichotomy_ge" (f32.const 0.0) (f32.const nan)) (i32.const 0))
  2242  (assert_return (invoke "f64.no_trichotomy_lt" (f64.const 0.0) (f64.const nan)) (i32.const 0))
  2243  (assert_return (invoke "f64.no_trichotomy_le" (f64.const 0.0) (f64.const nan)) (i32.const 0))
  2244  (assert_return (invoke "f64.no_trichotomy_gt" (f64.const 0.0) (f64.const nan)) (i32.const 0))
  2245  (assert_return (invoke "f64.no_trichotomy_ge" (f64.const 0.0) (f64.const nan)) (i32.const 0))
  2246  
  2247  ;; Some test harnesses which can run this testsuite are unable to perform tests
  2248  ;; of NaN bitpatterns. The following tests whether the underlying platform is
  2249  ;; generally producing the kinds of NaNs expected.
  2250  (module
  2251    (func (export "f32.arithmetic_nan_bitpattern")
  2252          (param $x i32) (param $y i32) (result i32)
  2253      (i32.and (i32.reinterpret_f32
  2254                 (f32.div
  2255                   (f32.reinterpret_i32 (local.get $x))
  2256                   (f32.reinterpret_i32 (local.get $y))))
  2257               (i32.const 0x7fc00000)))
  2258    (func (export "f32.canonical_nan_bitpattern")
  2259          (param $x i32) (param $y i32) (result i32)
  2260      (i32.and (i32.reinterpret_f32
  2261                 (f32.div
  2262                   (f32.reinterpret_i32 (local.get $x))
  2263                   (f32.reinterpret_i32 (local.get $y))))
  2264               (i32.const 0x7fffffff)))
  2265    (func (export "f32.nonarithmetic_nan_bitpattern")
  2266          (param $x i32) (result i32)
  2267      (i32.reinterpret_f32 (f32.neg (f32.reinterpret_i32 (local.get $x)))))
  2268  
  2269    (func (export "f64.arithmetic_nan_bitpattern")
  2270          (param $x i64) (param $y i64) (result i64)
  2271      (i64.and (i64.reinterpret_f64
  2272                 (f64.div
  2273                   (f64.reinterpret_i64 (local.get $x))
  2274                   (f64.reinterpret_i64 (local.get $y))))
  2275               (i64.const 0x7ff8000000000000)))
  2276    (func (export "f64.canonical_nan_bitpattern")
  2277          (param $x i64) (param $y i64) (result i64)
  2278      (i64.and (i64.reinterpret_f64
  2279                 (f64.div
  2280                   (f64.reinterpret_i64 (local.get $x))
  2281                   (f64.reinterpret_i64 (local.get $y))))
  2282               (i64.const 0x7fffffffffffffff)))
  2283    (func (export "f64.nonarithmetic_nan_bitpattern")
  2284          (param $x i64) (result i64)
  2285      (i64.reinterpret_f64 (f64.neg (f64.reinterpret_i64 (local.get $x)))))
  2286  
  2287    ;; Versions of no_fold testcases that only care about NaN bitpatterns.
  2288    (func (export "f32.no_fold_sub_zero") (param $x i32) (result i32)
  2289      (i32.and (i32.reinterpret_f32 (f32.sub (f32.reinterpret_i32 (local.get $x)) (f32.const 0.0)))
  2290               (i32.const 0x7fc00000)))
  2291    (func (export "f32.no_fold_neg0_sub") (param $x i32) (result i32)
  2292      (i32.and (i32.reinterpret_f32 (f32.sub (f32.const -0.0) (f32.reinterpret_i32 (local.get $x))))
  2293               (i32.const 0x7fc00000)))
  2294    (func (export "f32.no_fold_mul_one") (param $x i32) (result i32)
  2295      (i32.and (i32.reinterpret_f32 (f32.mul (f32.reinterpret_i32 (local.get $x)) (f32.const 1.0)))
  2296               (i32.const 0x7fc00000)))
  2297    (func (export "f32.no_fold_neg1_mul") (param $x i32) (result i32)
  2298      (i32.and (i32.reinterpret_f32 (f32.mul (f32.const -1.0) (f32.reinterpret_i32 (local.get $x))))
  2299               (i32.const 0x7fc00000)))
  2300    (func (export "f32.no_fold_div_one") (param $x i32) (result i32)
  2301      (i32.and (i32.reinterpret_f32 (f32.div (f32.reinterpret_i32 (local.get $x)) (f32.const 1.0)))
  2302               (i32.const 0x7fc00000)))
  2303    (func (export "f32.no_fold_div_neg1") (param $x i32) (result i32)
  2304      (i32.and (i32.reinterpret_f32 (f32.div (f32.reinterpret_i32 (local.get $x)) (f32.const -1.0)))
  2305               (i32.const 0x7fc00000)))
  2306    (func (export "f64.no_fold_sub_zero") (param $x i64) (result i64)
  2307      (i64.and (i64.reinterpret_f64 (f64.sub (f64.reinterpret_i64 (local.get $x)) (f64.const 0.0)))
  2308               (i64.const 0x7ff8000000000000)))
  2309    (func (export "f64.no_fold_neg0_sub") (param $x i64) (result i64)
  2310      (i64.and (i64.reinterpret_f64 (f64.sub (f64.const -0.0) (f64.reinterpret_i64 (local.get $x))))
  2311               (i64.const 0x7ff8000000000000)))
  2312    (func (export "f64.no_fold_mul_one") (param $x i64) (result i64)
  2313      (i64.and (i64.reinterpret_f64 (f64.mul (f64.reinterpret_i64 (local.get $x)) (f64.const 1.0)))
  2314               (i64.const 0x7ff8000000000000)))
  2315    (func (export "f64.no_fold_neg1_mul") (param $x i64) (result i64)
  2316      (i64.and (i64.reinterpret_f64 (f64.mul (f64.const -1.0) (f64.reinterpret_i64 (local.get $x))))
  2317               (i64.const 0x7ff8000000000000)))
  2318    (func (export "f64.no_fold_div_one") (param $x i64) (result i64)
  2319      (i64.and (i64.reinterpret_f64 (f64.div (f64.reinterpret_i64 (local.get $x)) (f64.const 1.0)))
  2320               (i64.const 0x7ff8000000000000)))
  2321    (func (export "f64.no_fold_div_neg1") (param $x i64) (result i64)
  2322      (i64.and (i64.reinterpret_f64 (f64.div (f64.reinterpret_i64 (local.get $x)) (f64.const -1.0)))
  2323               (i64.const 0x7ff8000000000000)))
  2324    (func (export "no_fold_promote_demote") (param $x i32) (result i32)
  2325      (i32.and (i32.reinterpret_f32 (f32.demote_f64 (f64.promote_f32 (f32.reinterpret_i32 (local.get $x)))))
  2326               (i32.const 0x7fc00000)))
  2327  )
  2328  
  2329  (assert_return (invoke "f32.arithmetic_nan_bitpattern" (i32.const 0x7f803210) (i32.const 0x7f803210)) (i32.const 0x7fc00000))
  2330  (assert_return (invoke "f32.canonical_nan_bitpattern" (i32.const 0) (i32.const 0)) (i32.const 0x7fc00000))
  2331  (assert_return (invoke "f32.canonical_nan_bitpattern" (i32.const 0x7fc00000) (i32.const 0x7fc00000)) (i32.const 0x7fc00000))
  2332  (assert_return (invoke "f32.canonical_nan_bitpattern" (i32.const 0xffc00000) (i32.const 0x7fc00000)) (i32.const 0x7fc00000))
  2333  (assert_return (invoke "f32.canonical_nan_bitpattern" (i32.const 0x7fc00000) (i32.const 0xffc00000)) (i32.const 0x7fc00000))
  2334  (assert_return (invoke "f32.canonical_nan_bitpattern" (i32.const 0xffc00000) (i32.const 0xffc00000)) (i32.const 0x7fc00000))
  2335  (assert_return (invoke "f32.nonarithmetic_nan_bitpattern" (i32.const 0x7fc03210)) (i32.const 0xffc03210))
  2336  (assert_return (invoke "f32.nonarithmetic_nan_bitpattern" (i32.const 0xffc03210)) (i32.const 0x7fc03210))
  2337  (assert_return (invoke "f32.nonarithmetic_nan_bitpattern" (i32.const 0x7f803210)) (i32.const 0xff803210))
  2338  (assert_return (invoke "f32.nonarithmetic_nan_bitpattern" (i32.const 0xff803210)) (i32.const 0x7f803210))
  2339  (assert_return (invoke "f64.arithmetic_nan_bitpattern" (i64.const 0x7ff0000000003210) (i64.const 0x7ff0000000003210)) (i64.const 0x7ff8000000000000))
  2340  (assert_return (invoke "f64.canonical_nan_bitpattern" (i64.const 0) (i64.const 0)) (i64.const 0x7ff8000000000000))
  2341  (assert_return (invoke "f64.canonical_nan_bitpattern" (i64.const 0x7ff8000000000000) (i64.const 0x7ff8000000000000)) (i64.const 0x7ff8000000000000))
  2342  (assert_return (invoke "f64.canonical_nan_bitpattern" (i64.const 0xfff8000000000000) (i64.const 0x7ff8000000000000)) (i64.const 0x7ff8000000000000))
  2343  (assert_return (invoke "f64.canonical_nan_bitpattern" (i64.const 0x7ff8000000000000) (i64.const 0xfff8000000000000)) (i64.const 0x7ff8000000000000))
  2344  (assert_return (invoke "f64.canonical_nan_bitpattern" (i64.const 0xfff8000000000000) (i64.const 0xfff8000000000000)) (i64.const 0x7ff8000000000000))
  2345  (assert_return (invoke "f64.nonarithmetic_nan_bitpattern" (i64.const 0x7ff8000000003210)) (i64.const 0xfff8000000003210))
  2346  (assert_return (invoke "f64.nonarithmetic_nan_bitpattern" (i64.const 0xfff8000000003210)) (i64.const 0x7ff8000000003210))
  2347  (assert_return (invoke "f64.nonarithmetic_nan_bitpattern" (i64.const 0x7ff0000000003210)) (i64.const 0xfff0000000003210))
  2348  (assert_return (invoke "f64.nonarithmetic_nan_bitpattern" (i64.const 0xfff0000000003210)) (i64.const 0x7ff0000000003210))
  2349  (assert_return (invoke "f32.no_fold_sub_zero" (i32.const 0x7fa00000)) (i32.const 0x7fc00000))
  2350  (assert_return (invoke "f32.no_fold_neg0_sub" (i32.const 0x7fa00000)) (i32.const 0x7fc00000))
  2351  (assert_return (invoke "f32.no_fold_mul_one" (i32.const 0x7fa00000)) (i32.const 0x7fc00000))
  2352  (assert_return (invoke "f32.no_fold_neg1_mul" (i32.const 0x7fa00000)) (i32.const 0x7fc00000))
  2353  (assert_return (invoke "f32.no_fold_div_one" (i32.const 0x7fa00000)) (i32.const 0x7fc00000))
  2354  (assert_return (invoke "f32.no_fold_div_neg1" (i32.const 0x7fa00000)) (i32.const 0x7fc00000))
  2355  (assert_return (invoke "f64.no_fold_sub_zero" (i64.const 0x7ff4000000000000)) (i64.const 0x7ff8000000000000))
  2356  (assert_return (invoke "f64.no_fold_neg0_sub" (i64.const 0x7ff4000000000000)) (i64.const 0x7ff8000000000000))
  2357  (assert_return (invoke "f64.no_fold_mul_one" (i64.const 0x7ff4000000000000)) (i64.const 0x7ff8000000000000))
  2358  (assert_return (invoke "f64.no_fold_neg1_mul" (i64.const 0x7ff4000000000000)) (i64.const 0x7ff8000000000000))
  2359  (assert_return (invoke "f64.no_fold_div_one" (i64.const 0x7ff4000000000000)) (i64.const 0x7ff8000000000000))
  2360  (assert_return (invoke "f64.no_fold_div_neg1" (i64.const 0x7ff4000000000000)) (i64.const 0x7ff8000000000000))
  2361  (assert_return (invoke "no_fold_promote_demote" (i32.const 0x7fa00000)) (i32.const 0x7fc00000))
  2362  
  2363  ;; Test that IEEE 754 double precision does, in fact, compute a certain dot
  2364  ;; product correctly.
  2365  
  2366  (module
  2367    (func (export "dot_product_example")
  2368          (param $x0 f64) (param $x1 f64) (param $x2 f64) (param $x3 f64)
  2369          (param $y0 f64) (param $y1 f64) (param $y2 f64) (param $y3 f64)
  2370          (result f64)
  2371      (f64.add (f64.add (f64.add
  2372        (f64.mul (local.get $x0) (local.get $y0))
  2373        (f64.mul (local.get $x1) (local.get $y1)))
  2374        (f64.mul (local.get $x2) (local.get $y2)))
  2375        (f64.mul (local.get $x3) (local.get $y3)))
  2376    )
  2377  
  2378    (func (export "with_binary_sum_collapse")
  2379          (param $x0 f64) (param $x1 f64) (param $x2 f64) (param $x3 f64)
  2380          (param $y0 f64) (param $y1 f64) (param $y2 f64) (param $y3 f64)
  2381          (result f64)
  2382        (f64.add (f64.add (f64.mul (local.get $x0) (local.get $y0))
  2383                          (f64.mul (local.get $x1) (local.get $y1)))
  2384                 (f64.add (f64.mul (local.get $x2) (local.get $y2))
  2385                          (f64.mul (local.get $x3) (local.get $y3))))
  2386    )
  2387  )
  2388  
  2389  (assert_return (invoke "dot_product_example"
  2390      (f64.const 3.2e7) (f64.const 1.0) (f64.const -1.0) (f64.const 8.0e7)
  2391      (f64.const 4.0e7) (f64.const 1.0) (f64.const -1.0) (f64.const -1.6e7))
  2392    (f64.const 2.0))
  2393  (assert_return (invoke "with_binary_sum_collapse"
  2394      (f64.const 3.2e7) (f64.const 1.0) (f64.const -1.0) (f64.const 8.0e7)
  2395      (f64.const 4.0e7) (f64.const 1.0) (f64.const -1.0) (f64.const -1.6e7))
  2396    (f64.const 2.0))
  2397  
  2398  ;; http://www.vinc17.org/research/fptest.en.html#contract2fma
  2399  
  2400  (module
  2401    (func (export "f32.contract2fma")
  2402          (param $x f32) (param $y f32) (result f32)
  2403      (f32.sqrt (f32.sub (f32.mul (local.get $x) (local.get $x))
  2404                         (f32.mul (local.get $y) (local.get $y)))))
  2405    (func (export "f64.contract2fma")
  2406          (param $x f64) (param $y f64) (result f64)
  2407      (f64.sqrt (f64.sub (f64.mul (local.get $x) (local.get $x))
  2408                         (f64.mul (local.get $y) (local.get $y)))))
  2409  )
  2410  
  2411  (assert_return (invoke "f32.contract2fma" (f32.const 1.0) (f32.const 1.0)) (f32.const 0.0))
  2412  (assert_return (invoke "f32.contract2fma" (f32.const 0x1.19999ap+0) (f32.const 0x1.19999ap+0)) (f32.const 0.0))
  2413  (assert_return (invoke "f32.contract2fma" (f32.const 0x1.333332p+0) (f32.const 0x1.333332p+0)) (f32.const 0.0))
  2414  (assert_return (invoke "f64.contract2fma" (f64.const 1.0) (f64.const 1.0)) (f64.const 0.0))
  2415  (assert_return (invoke "f64.contract2fma" (f64.const 0x1.199999999999ap+0) (f64.const 0x1.199999999999ap+0)) (f64.const 0.0))
  2416  (assert_return (invoke "f64.contract2fma" (f64.const 0x1.3333333333333p+0) (f64.const 0x1.3333333333333p+0)) (f64.const 0.0))
  2417  
  2418  ;; Test that floating-point isn't implemented with QuickBasic for MS-DOS.
  2419  ;; https://support.microsoft.com/en-us/help/42980/-complete-tutorial-to-understand-ieee-floating-point-errors
  2420  
  2421  (module
  2422    (func (export "f32.division_by_small_number")
  2423          (param $a f32) (param $b f32) (param $c f32) (result f32)
  2424      (f32.sub (local.get $a) (f32.div (local.get $b) (local.get $c))))
  2425    (func (export "f64.division_by_small_number")
  2426          (param $a f64) (param $b f64) (param $c f64) (result f64)
  2427      (f64.sub (local.get $a) (f64.div (local.get $b) (local.get $c))))
  2428  )
  2429  
  2430  (assert_return (invoke "f32.division_by_small_number" (f32.const 112000000) (f32.const 100000) (f32.const 0.0009)) (f32.const 888888))
  2431  (assert_return (invoke "f64.division_by_small_number" (f64.const 112000000) (f64.const 100000) (f64.const 0.0009)) (f64.const 888888.8888888806))
  2432  
  2433  ;; Test a simple golden ratio computation.
  2434  ;; http://mathworld.wolfram.com/GoldenRatio.html
  2435  
  2436  (module
  2437    (func (export "f32.golden_ratio") (param $a f32) (param $b f32) (param $c f32) (result f32)
  2438      (f32.mul (local.get 0) (f32.add (local.get 1) (f32.sqrt (local.get 2)))))
  2439    (func (export "f64.golden_ratio") (param $a f64) (param $b f64) (param $c f64) (result f64)
  2440      (f64.mul (local.get 0) (f64.add (local.get 1) (f64.sqrt (local.get 2)))))
  2441  )
  2442  
  2443  (assert_return (invoke "f32.golden_ratio" (f32.const 0.5) (f32.const 1.0) (f32.const 5.0)) (f32.const 1.618034))
  2444  (assert_return (invoke "f64.golden_ratio" (f64.const 0.5) (f64.const 1.0) (f64.const 5.0)) (f64.const 1.618033988749895))
  2445  
  2446  ;; Test some silver means computations.
  2447  ;; http://mathworld.wolfram.com/SilverRatio.html
  2448  
  2449  (module
  2450    (func (export "f32.silver_means") (param $n f32) (result f32)
  2451      (f32.mul (f32.const 0.5)
  2452               (f32.add (local.get $n)
  2453                        (f32.sqrt (f32.add (f32.mul (local.get $n) (local.get $n))
  2454                                           (f32.const 4.0))))))
  2455    (func (export "f64.silver_means") (param $n f64) (result f64)
  2456      (f64.mul (f64.const 0.5)
  2457               (f64.add (local.get $n)
  2458                        (f64.sqrt (f64.add (f64.mul (local.get $n) (local.get $n))
  2459                                           (f64.const 4.0))))))
  2460  )
  2461  
  2462  (assert_return (invoke "f32.silver_means" (f32.const 0.0)) (f32.const 1.0))
  2463  (assert_return (invoke "f32.silver_means" (f32.const 1.0)) (f32.const 1.6180340))
  2464  (assert_return (invoke "f32.silver_means" (f32.const 2.0)) (f32.const 2.4142136))
  2465  (assert_return (invoke "f32.silver_means" (f32.const 3.0)) (f32.const 3.3027756))
  2466  (assert_return (invoke "f32.silver_means" (f32.const 4.0)) (f32.const 4.2360680))
  2467  (assert_return (invoke "f32.silver_means" (f32.const 5.0)) (f32.const 5.1925821))
  2468  (assert_return (invoke "f64.silver_means" (f64.const 0.0)) (f64.const 1.0))
  2469  (assert_return (invoke "f64.silver_means" (f64.const 1.0)) (f64.const 1.618033988749895))
  2470  (assert_return (invoke "f64.silver_means" (f64.const 2.0)) (f64.const 2.414213562373095))
  2471  (assert_return (invoke "f64.silver_means" (f64.const 3.0)) (f64.const 3.302775637731995))
  2472  (assert_return (invoke "f64.silver_means" (f64.const 4.0)) (f64.const 4.236067977499790))
  2473  (assert_return (invoke "f64.silver_means" (f64.const 5.0)) (f64.const 5.192582403567252))
  2474  
  2475  ;; Test that an f64 0.4 isn't double-rounded as via extended precision.
  2476  ;; https://bugs.llvm.org/show_bug.cgi?id=11200
  2477  
  2478  (module
  2479    (func (export "point_four") (param $four f64) (param $ten f64) (result i32)
  2480      (f64.lt (f64.div (local.get $four) (local.get $ten)) (f64.const 0.4)))
  2481  )
  2482  
  2483  (assert_return (invoke "point_four" (f64.const 4.0) (f64.const 10.0)) (i32.const 0))
  2484  
  2485  ;; Test an approximation function for tau; it should produces the correctly
  2486  ;; rounded result after (and only after) the expected number of iterations.
  2487  
  2488  (module
  2489    (func (export "tau") (param i32) (result f64)
  2490      (local f64 f64 f64 f64)
  2491      f64.const 0x0p+0
  2492      local.set 1
  2493      block
  2494        local.get 0
  2495        i32.const 1
  2496        i32.lt_s
  2497        br_if 0
  2498        f64.const 0x1p+0
  2499        local.set 2
  2500        f64.const 0x0p+0
  2501        local.set 3
  2502        loop
  2503          local.get 1
  2504          local.get 2
  2505          f64.const 0x1p+3
  2506          local.get 3
  2507          f64.const 0x1p+3
  2508          f64.mul
  2509          local.tee 4
  2510          f64.const 0x1p+0
  2511          f64.add
  2512          f64.div
  2513          f64.const 0x1p+2
  2514          local.get 4
  2515          f64.const 0x1p+2
  2516          f64.add
  2517          f64.div
  2518          f64.sub
  2519          f64.const 0x1p+1
  2520          local.get 4
  2521          f64.const 0x1.4p+2
  2522          f64.add
  2523          f64.div
  2524          f64.sub
  2525          f64.const 0x1p+1
  2526          local.get 4
  2527          f64.const 0x1.8p+2
  2528          f64.add
  2529          f64.div
  2530          f64.sub
  2531          f64.mul
  2532          f64.add
  2533          local.set 1
  2534          local.get 3
  2535          f64.const 0x1p+0
  2536          f64.add
  2537          local.set 3
  2538          local.get 2
  2539          f64.const 0x1p-4
  2540          f64.mul
  2541          local.set 2
  2542          local.get 0
  2543          i32.const -1
  2544          i32.add
  2545          local.tee 0
  2546          br_if 0
  2547        end
  2548      end
  2549      local.get 1
  2550    )
  2551  )
  2552  
  2553  (assert_return (invoke "tau" (i32.const 10)) (f64.const 0x1.921fb54442d14p+2))
  2554  (assert_return (invoke "tau" (i32.const 11)) (f64.const 0x1.921fb54442d18p+2))
  2555  
  2556  ;; Test that y < 0 ? x : (x + 1) is not folded to x + (y < 0).
  2557  
  2558  (module
  2559    (func (export "f32.no_fold_conditional_inc") (param $x f32) (param $y f32) (result f32)
  2560      (select (local.get $x)
  2561              (f32.add (local.get $x) (f32.const 1.0))
  2562              (f32.lt (local.get $y) (f32.const 0.0))))
  2563    (func (export "f64.no_fold_conditional_inc") (param $x f64) (param $y f64) (result f64)
  2564      (select (local.get $x)
  2565              (f64.add (local.get $x) (f64.const 1.0))
  2566              (f64.lt (local.get $y) (f64.const 0.0))))
  2567  )
  2568  
  2569  (assert_return (invoke "f32.no_fold_conditional_inc" (f32.const -0.0) (f32.const -1.0)) (f32.const -0.0))
  2570  (assert_return (invoke "f64.no_fold_conditional_inc" (f64.const -0.0) (f64.const -1.0)) (f64.const -0.0))