From f8897b17ab2fab9202d323c9ed94b9186c966ca6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 5 Jul 2016 08:45:24 -0700 Subject: [PATCH 01/13] Add more tests, delete some redundant tests, and reorganize some existing tests. --- ml-proto/TestingTodo.md | 2 +- ml-proto/test/conversions.wast | 2 - ml-proto/test/float_exprs.wast | 308 +++++++++++++++++++++++++-- ml-proto/test/float_misc.wast | 188 ++++++++++------ ml-proto/test/i32.wast | 16 ++ ml-proto/test/i64.wast | 16 ++ ml-proto/test/memory_redundancy.wast | 9 +- 7 files changed, 451 insertions(+), 90 deletions(-) diff --git a/ml-proto/TestingTodo.md b/ml-proto/TestingTodo.md index a0cdd22b59..f725f2a5d7 100644 --- a/ml-proto/TestingTodo.md +++ b/ml-proto/TestingTodo.md @@ -15,7 +15,7 @@ Misc semantics: - test that one can clobber the entire contents of the linear memory without corrupting: call stack, local variables, program execution. Operator semantics: - - test that promote/demote, sext/trunc, zext/trunc is bit-preserving if not NaN + - ~~test that promote/demote is bit-preserving if not NaN~~ - ~~test that clz/ctz handle zero~~ - ~~test that numbers slightly outside of the int32 range round into the int32 range in floating-to-int32 conversion~~ - ~~test that neg, abs, copysign, reinterpretcast, store+load, set+get, preserve the sign bit and significand bits of NaN and don't canonicalize~~ diff --git a/ml-proto/test/conversions.wast b/ml-proto/test/conversions.wast index 4671b0d4ae..91ee9d67a5 100644 --- a/ml-proto/test/conversions.wast +++ b/ml-proto/test/conversions.wast @@ -387,8 +387,6 @@ (assert_return (invoke "f32.demote_f64" (f64.const nan)) (f32.const nan)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1p-1022)) (f32.const 0.0)) (assert_return (invoke "f32.demote_f64" (f64.const -0x1p-1022)) (f32.const -0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x0.0000000000001p-1022)) (f32.const 0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x0.0000000000001p-1022)) (f32.const -0.0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x0.8p-149)) (f32.const 0.0)) (assert_return (invoke "f32.demote_f64" (f64.const -0x0.8p-149)) (f32.const -0.0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000000000001p-150)) (f32.const 0x1p-149)) diff --git a/ml-proto/test/float_exprs.wast b/ml-proto/test/float_exprs.wast index 2258d02ed1..db20472de5 100644 --- a/ml-proto/test/float_exprs.wast +++ b/ml-proto/test/float_exprs.wast @@ -500,44 +500,54 @@ ;; Test that 1.0/x isn't approximated. (module - (func $f32.no_approximate_reciprocal (param $x f32) (param $y f32) (result f32) + (func $f32.no_approximate_reciprocal (param $x f32) (result f32) (f32.div (f32.const 1.0) (get_local $x))) (export "f32.no_approximate_reciprocal" $f32.no_approximate_reciprocal) ) -(assert_return (invoke "f32.no_approximate_reciprocal" (f32.const -0x1.2900b6p-10) (f32.const 0x1.d427e8p+56)) (f32.const -0x1.b950d4p+9)) -(assert_return (invoke "f32.no_approximate_reciprocal" (f32.const 0x1.e7212p+127) (f32.const -0x1.55832ap+44)) (f32.const 0x1.0d11f8p-128)) -(assert_return (invoke "f32.no_approximate_reciprocal" (f32.const -0x1.42a466p-93) (f32.const 0x1.7b62d8p+36)) (f32.const -0x1.963ee6p+92)) -(assert_return (invoke "f32.no_approximate_reciprocal" (f32.const 0x1.5d0c32p+76) (f32.const 0x1.d14dccp-74)) (f32.const 0x1.778362p-77)) -(assert_return (invoke "f32.no_approximate_reciprocal" (f32.const -0x1.601de2p-82) (f32.const -0x1.3c7abap+42)) (f32.const -0x1.743d7ep+81)) +(assert_return (invoke "f32.no_approximate_reciprocal" (f32.const -0x1.2900b6p-10)) (f32.const -0x1.b950d4p+9)) +(assert_return (invoke "f32.no_approximate_reciprocal" (f32.const 0x1.e7212p+127)) (f32.const 0x1.0d11f8p-128)) +(assert_return (invoke "f32.no_approximate_reciprocal" (f32.const -0x1.42a466p-93)) (f32.const -0x1.963ee6p+92)) +(assert_return (invoke "f32.no_approximate_reciprocal" (f32.const 0x1.5d0c32p+76)) (f32.const 0x1.778362p-77)) +(assert_return (invoke "f32.no_approximate_reciprocal" (f32.const -0x1.601de2p-82)) (f32.const -0x1.743d7ep+81)) -;; Test that 1.0/sqrt(x) isn't approximated. +;; Test that 1.0/sqrt(x) isn't approximated or fused. (module - (func $f32.no_approximate_reciprocal_sqrt (param $x f32) (param $y f32) (result f32) + (func $f32.no_approximate_reciprocal_sqrt (param $x f32) (result f32) (f32.div (f32.const 1.0) (f32.sqrt (get_local $x)))) (export "f32.no_approximate_reciprocal_sqrt" $f32.no_approximate_reciprocal_sqrt) + + (func $f64.no_fuse_reciprocal_sqrt (param $x f64) (result f64) + (f64.div (f64.const 1.0) (f64.sqrt (get_local $x)))) + (export "f64.no_fuse_reciprocal_sqrt" $f64.no_fuse_reciprocal_sqrt) ) -(assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.6af12ap-43) (f32.const 0x1.b2113ap-14)) (f32.const 0x1.300ed4p+21)) -(assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.e82fc6p-8) (f32.const -0x1.56a382p-126)) (f32.const 0x1.72c376p+3)) -(assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.b9fa9cp-66) (f32.const -0x1.35394cp+35)) (f32.const 0x1.85a9bap+32)) -(assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.f4f546p-44) (f32.const -0x1.c92ecep+122)) (f32.const 0x1.6e01c2p+21)) -(assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.5da7aap-86) (f32.const -0x1.665652p+119)) (f32.const 0x1.b618cap+42)) +(assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.6af12ap-43)) (f32.const 0x1.300ed4p+21)) +(assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.e82fc6p-8)) (f32.const 0x1.72c376p+3)) +(assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.b9fa9cp-66)) (f32.const 0x1.85a9bap+32)) +(assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.f4f546p-44)) (f32.const 0x1.6e01c2p+21)) +(assert_return (invoke "f32.no_approximate_reciprocal_sqrt" (f32.const 0x1.5da7aap-86)) (f32.const 0x1.b618cap+42)) + +(assert_return (invoke "f64.no_fuse_reciprocal_sqrt" (f64.const 0x1.1568a63b55fa3p+889)) (f64.const 0x1.5bc9c74c9952p-445)) +(assert_return (invoke "f64.no_fuse_reciprocal_sqrt" (f64.const 0x1.239fcd0939cafp+311)) (f64.const 0x1.5334a922b4818p-156)) +(assert_return (invoke "f64.no_fuse_reciprocal_sqrt" (f64.const 0x1.6e36a24e11054p+104)) (f64.const 0x1.ac13f20977f29p-53)) +(assert_return (invoke "f64.no_fuse_reciprocal_sqrt" (f64.const 0x1.23ee173219f83p+668)) (f64.const 0x1.df753e055862dp-335)) +(assert_return (invoke "f64.no_fuse_reciprocal_sqrt" (f64.const 0x1.b30f74caf9babp+146)) (f64.const 0x1.88bfc3d1764a9p-74)) ;; Test that sqrt(1.0/x) isn't approximated. (module - (func $f32.no_approximate_sqrt_reciprocal (param $x f32) (param $y f32) (result f32) + (func $f32.no_approximate_sqrt_reciprocal (param $x f32) (result f32) (f32.sqrt (f32.div (f32.const 1.0) (get_local $x)))) (export "f32.no_approximate_sqrt_reciprocal" $f32.no_approximate_sqrt_reciprocal) ) -(assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.a4c986p+60) (f32.const -0x1.04e29cp-72)) (f32.const 0x1.8f5ac6p-31)) -(assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.50511ep-9) (f32.const -0x1.39228ep-32)) (f32.const 0x1.3bdd46p+4)) -(assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.125ec2p+69) (f32.const -0x1.a7f42ep+92)) (f32.const 0x1.5db572p-35)) -(assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.ba4c5p+13) (f32.const 0x1.947784p-72)) (f32.const 0x1.136f16p-7)) -(assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.4a5be2p+104) (f32.const 0x1.a7b718p-19)) (f32.const 0x1.c2b5bp-53)) +(assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.a4c986p+60)) (f32.const 0x1.8f5ac6p-31)) +(assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.50511ep-9)) (f32.const 0x1.3bdd46p+4)) +(assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.125ec2p+69)) (f32.const 0x1.5db572p-35)) +(assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.ba4c5p+13)) (f32.const 0x1.136f16p-7)) +(assert_return (invoke "f32.no_approximate_sqrt_reciprocal" (f32.const 0x1.4a5be2p+104)) (f32.const 0x1.c2b5bp-53)) ;; Test that converting i32/i64 to f32/f64 and back isn't folded away @@ -685,7 +695,8 @@ (assert_return (invoke "no_fold_demote_promote" (f64.const -0x1.74f5bd865163p-88)) (f64.const -0x1.74f5bep-88)) (assert_return (invoke "no_fold_demote_promote" (f64.const 0x1.26d675662367ep+104)) (f64.const 0x1.26d676p+104)) -;; Test that demote(promote(x)) is not folded to x. +;; Test that demote(promote(x)) is not folded to x, and aside from NaN is +;; bit-preserving. (module (func $no_fold_promote_demote (param $x f32) (result f32) @@ -694,6 +705,18 @@ ) (assert_return (invoke "no_fold_promote_demote" (f32.const nan:0x200000)) (f32.const nan:0x600000)) +(assert_return (invoke "no_fold_promote_demote" (f32.const 0x0p+0)) (f32.const 0x0p+0)) +(assert_return (invoke "no_fold_promote_demote" (f32.const -0x0p+0)) (f32.const -0x0p+0)) +(assert_return (invoke "no_fold_promote_demote" (f32.const 0x1p-149)) (f32.const 0x1p-149)) +(assert_return (invoke "no_fold_promote_demote" (f32.const -0x1p-149)) (f32.const -0x1p-149)) +(assert_return (invoke "no_fold_promote_demote" (f32.const 0x1.fffffcp-127)) (f32.const 0x1.fffffcp-127)) +(assert_return (invoke "no_fold_promote_demote" (f32.const -0x1.fffffcp-127)) (f32.const -0x1.fffffcp-127)) +(assert_return (invoke "no_fold_promote_demote" (f32.const 0x1p-126)) (f32.const 0x1p-126)) +(assert_return (invoke "no_fold_promote_demote" (f32.const -0x1p-126)) (f32.const -0x1p-126)) +(assert_return (invoke "no_fold_promote_demote" (f32.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) +(assert_return (invoke "no_fold_promote_demote" (f32.const -0x1.fffffep+127)) (f32.const -0x1.fffffep+127)) +(assert_return (invoke "no_fold_promote_demote" (f32.const infinity)) (f32.const infinity)) +(assert_return (invoke "no_fold_promote_demote" (f32.const -infinity)) (f32.const -infinity)) ;; Test that demote(x+promote(y)) is not folded to demote(x)+y. @@ -1361,12 +1384,22 @@ (assert_return (invoke "f32.no_fold_recip_recip" (f32.const -0x1.e66982p+4)) (f32.const -0x1.e66984p+4)) (assert_return (invoke "f32.no_fold_recip_recip" (f32.const 0x1.f99916p+70)) (f32.const 0x1.f99914p+70)) +(assert_return (invoke "f32.no_fold_recip_recip" (f32.const -0x0p+0)) (f32.const -0x0p+0)) +(assert_return (invoke "f32.no_fold_recip_recip" (f32.const 0x0p+0)) (f32.const 0x0p+0)) +(assert_return (invoke "f32.no_fold_recip_recip" (f32.const -infinity)) (f32.const -infinity)) +(assert_return (invoke "f32.no_fold_recip_recip" (f32.const infinity)) (f32.const infinity)) + (assert_return (invoke "f64.no_fold_recip_recip" (f64.const -0x1.d81248dda63dp+148)) (f64.const -0x1.d81248dda63d1p+148)) (assert_return (invoke "f64.no_fold_recip_recip" (f64.const -0x1.f4750312039e3p+66)) (f64.const -0x1.f4750312039e2p+66)) (assert_return (invoke "f64.no_fold_recip_recip" (f64.const 0x1.fa50630eec7f6p+166)) (f64.const 0x1.fa50630eec7f5p+166)) (assert_return (invoke "f64.no_fold_recip_recip" (f64.const 0x1.db0598617ba92p-686)) (f64.const 0x1.db0598617ba91p-686)) (assert_return (invoke "f64.no_fold_recip_recip" (f64.const 0x1.85f1638a0c82bp+902)) (f64.const 0x1.85f1638a0c82ap+902)) +(assert_return (invoke "f64.no_fold_recip_recip" (f64.const -0x0p+0)) (f64.const -0x0p+0)) +(assert_return (invoke "f64.no_fold_recip_recip" (f64.const 0x0p+0)) (f64.const 0x0p+0)) +(assert_return (invoke "f64.no_fold_recip_recip" (f64.const -infinity)) (f64.const -infinity)) +(assert_return (invoke "f64.no_fold_recip_recip" (f64.const infinity)) (f64.const infinity)) + ;; Test that (x+y) * (x-y) is not optimized to x*x - y*y. (module @@ -1507,12 +1540,12 @@ (assert_return (invoke "f32.no_fold_neg_sub" (f32.const -0.0) (f32.const -0.0)) (f32.const -0.0)) (assert_return (invoke "f32.no_fold_neg_sub" (f32.const 0.0) (f32.const -0.0)) (f32.const -0.0)) (assert_return (invoke "f32.no_fold_neg_sub" (f32.const -0.0) (f32.const 0.0)) (f32.const 0.0)) -(assert_return (invoke "f32.no_fold_neg_sub" (f32.const 0.0) (f32.const -0.0)) (f32.const -0.0)) +(assert_return (invoke "f32.no_fold_neg_sub" (f32.const 0.0) (f32.const 0.0)) (f32.const -0.0)) (assert_return (invoke "f64.no_fold_neg_sub" (f64.const -0.0) (f64.const -0.0)) (f64.const -0.0)) (assert_return (invoke "f64.no_fold_neg_sub" (f64.const 0.0) (f64.const -0.0)) (f64.const -0.0)) (assert_return (invoke "f64.no_fold_neg_sub" (f64.const -0.0) (f64.const 0.0)) (f64.const 0.0)) -(assert_return (invoke "f64.no_fold_neg_sub" (f64.const 0.0) (f64.const -0.0)) (f64.const -0.0)) +(assert_return (invoke "f64.no_fold_neg_sub" (f64.const 0.0) (f64.const 0.0)) (f64.const -0.0)) ;; Test that -x + x is not folded to 0.0. @@ -1752,3 +1785,234 @@ (assert_return (invoke "f32.no_flush_intermediate_subnormal" (f32.const 0x1p-126) (f32.const 0x1p-23) (f32.const 0x1p23)) (f32.const 0x1p-126)) (assert_return (invoke "f64.no_flush_intermediate_subnormal" (f64.const 0x1p-1022) (f64.const 0x1p-52) (f64.const 0x1p52)) (f64.const 0x1p-1022)) + +;; Test corner cases of John Hauser's microarchitectural recoding scheme. +;; https://github.com/riscv/riscv-tests/blob/695b86a6fcbe06ffbed8891af7e6fe7bf2062543/isa/rv64uf/recoding.S + +(module + (func $f32.recoding_eq (param $x f32) (param $y f32) (result i32) + (f32.eq (f32.mul (get_local $x) (get_local $y)) (get_local $x))) + (export "f32.recoding_eq" $f32.recoding_eq) + + (func $f32.recoding_le (param $x f32) (param $y f32) (result i32) + (f32.le (f32.mul (get_local $x) (get_local $y)) (get_local $x))) + (export "f32.recoding_le" $f32.recoding_le) + + (func $f32.recoding_lt (param $x f32) (param $y f32) (result i32) + (f32.lt (f32.mul (get_local $x) (get_local $y)) (get_local $x))) + (export "f32.recoding_lt" $f32.recoding_lt) + + (func $f64.recoding_eq (param $x f64) (param $y f64) (result i32) + (f64.eq (f64.mul (get_local $x) (get_local $y)) (get_local $x))) + (export "f64.recoding_eq" $f64.recoding_eq) + + (func $f64.recoding_le (param $x f64) (param $y f64) (result i32) + (f64.le (f64.mul (get_local $x) (get_local $y)) (get_local $x))) + (export "f64.recoding_le" $f64.recoding_le) + + (func $f64.recoding_lt (param $x f64) (param $y f64) (result i32) + (f64.lt (f64.mul (get_local $x) (get_local $y)) (get_local $x))) + (export "f64.recoding_lt" $f64.recoding_lt) + + (func $recoding_demote (param $x f64) (param $y f32) (result f32) + (f32.mul (f32.demote/f64 (get_local $x)) (get_local $y))) + (export "recoding_demote" $recoding_demote) +) + +(assert_return (invoke "f32.recoding_eq" (f32.const -infinity) (f32.const 3.0)) (i32.const 1)) +(assert_return (invoke "f32.recoding_le" (f32.const -infinity) (f32.const 3.0)) (i32.const 1)) +(assert_return (invoke "f32.recoding_lt" (f32.const -infinity) (f32.const 3.0)) (i32.const 0)) + +(assert_return (invoke "f32.recoding_eq" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 1)) +(assert_return (invoke "f32.recoding_le" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 1)) +(assert_return (invoke "f32.recoding_lt" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 0)) + +(assert_return (invoke "f64.recoding_eq" (f64.const -infinity) (f64.const 3.0)) (i32.const 1)) +(assert_return (invoke "f64.recoding_le" (f64.const -infinity) (f64.const 3.0)) (i32.const 1)) +(assert_return (invoke "f64.recoding_lt" (f64.const -infinity) (f64.const 3.0)) (i32.const 0)) + +(assert_return (invoke "f64.recoding_eq" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 1)) +(assert_return (invoke "f64.recoding_le" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 1)) +(assert_return (invoke "f64.recoding_lt" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 0)) + +(assert_return (invoke "recoding_demote" (f64.const 0x1.4c8f8p-132) (f32.const 1221)) (f32.const 0x1.8c8a1cp-122)) + +;; Test that division is not done as on an extended-base system. +;; http://www.ucbtest.org/goldberg/addendum.html + +(module + (func $f32.no_extended_precision_div (param $x f32) (param $y f32) (param $z f32) (result i32) + (f32.eq (f32.div (get_local $x) (get_local $y)) (get_local $z))) + (export "f32.no_extended_precision_div" $f32.no_extended_precision_div) + + (func $f64.no_extended_precision_div (param $x f64) (param $y f64) (param $z f64) (result i32) + (f64.eq (f64.div (get_local $x) (get_local $y)) (get_local $z))) + (export "f64.no_extended_precision_div" $f64.no_extended_precision_div) +) + +(assert_return (invoke "f32.no_extended_precision_div" (f32.const 3.0) (f32.const 7.0) (f32.const 0x1.b6db6ep-2)) (i32.const 1)) +(assert_return (invoke "f64.no_extended_precision_div" (f64.const 3.0) (f64.const 7.0) (f64.const 0x1.b6db6db6db6dbp-2)) (i32.const 1)) + +;; a*x + b*x == (a+b)*x for all x only if the operations a*x, b*x, and (a+b) +;; are all exact operations, which is true only if a and b are exact powers of +;; 2. Even then, if a==-b and x==-0, then a*x+b*x==0.0, (a+b)*x==-0.0. +;; https://dlang.org/d-floating-point.html + +(module + (func $f32.no_distribute_exact (param $x f32) (result f32) + (f32.add (f32.mul (f32.const -8.0) (get_local $x)) (f32.mul (f32.const 8.0) (get_local $x)))) + (export "f32.no_distribute_exact" $f32.no_distribute_exact) + + (func $f64.no_distribute_exact (param $x f64) (result f64) + (f64.add (f64.mul (f64.const -8.0) (get_local $x)) (f64.mul (f64.const 8.0) (get_local $x)))) + (export "f64.no_distribute_exact" $f64.no_distribute_exact) +) + +(assert_return (invoke "f32.no_distribute_exact" (f32.const -0.0)) (f32.const 0.0)) +(assert_return (invoke "f64.no_distribute_exact" (f64.const -0.0)) (f64.const 0.0)) + +;; Test various approximations of sqrt(2), sqrt(3), and sqrt(5). +;; https://xkcd.com/1047/ +(module + (func $f32.sqrt (param f32) (result f32) + (f32.sqrt (get_local 0))) + (export "f32.sqrt" $f32.sqrt) + + (func $f32.xkcd_sqrt_2 (param f32) (param f32) (param f32) (param f32) (result f32) + (f32.add (f32.div (get_local 0) (get_local 1)) (f32.div (get_local 2) (f32.sub (get_local 3) (get_local 2))))) + (export "f32.xkcd_sqrt_2" $f32.xkcd_sqrt_2) + + (func $f32.xkcd_sqrt_3 (param f32) (param f32) (param f32) (result f32) + (f32.div (f32.mul (get_local 0) (get_local 1)) (get_local 2))) + (export "f32.xkcd_sqrt_3" $f32.xkcd_sqrt_3) + + (func $f32.xkcd_sqrt_5 (param f32) (param f32) (param f32) (result f32) + (f32.add (f32.div (get_local 0) (get_local 1)) (f32.div (get_local 2) (get_local 0)))) + (export "f32.xkcd_sqrt_5" $f32.xkcd_sqrt_5) + + (func $f32.xkcd_better_sqrt_5 (param f32) (param f32) (param f32) (param f32) (result f32) + (f32.div (f32.add (get_local 0) (f32.mul (get_local 1) (get_local 2))) (f32.sub (get_local 3) (f32.mul (get_local 1) (get_local 2))))) + (export "f32.xkcd_better_sqrt_5" $f32.xkcd_better_sqrt_5) + + (func $f64.sqrt (param f64) (result f64) + (f64.sqrt (get_local 0))) + (export "f64.sqrt" $f64.sqrt) + + (func $f64.xkcd_sqrt_2 (param f64) (param f64) (param f64) (param f64) (result f64) + (f64.add (f64.div (get_local 0) (get_local 1)) (f64.div (get_local 2) (f64.sub (get_local 3) (get_local 2))))) + (export "f64.xkcd_sqrt_2" $f64.xkcd_sqrt_2) + + (func $f64.xkcd_sqrt_3 (param f64) (param f64) (param f64) (result f64) + (f64.div (f64.mul (get_local 0) (get_local 1)) (get_local 2))) + (export "f64.xkcd_sqrt_3" $f64.xkcd_sqrt_3) + + (func $f64.xkcd_sqrt_5 (param f64) (param f64) (param f64) (result f64) + (f64.add (f64.div (get_local 0) (get_local 1)) (f64.div (get_local 2) (get_local 0)))) + (export "f64.xkcd_sqrt_5" $f64.xkcd_sqrt_5) + + (func $f64.xkcd_better_sqrt_5 (param f64) (param f64) (param f64) (param f64) (result f64) + (f64.div (f64.add (get_local 0) (f64.mul (get_local 1) (get_local 2))) (f64.sub (get_local 3) (f64.mul (get_local 1) (get_local 2))))) + (export "f64.xkcd_better_sqrt_5" $f64.xkcd_better_sqrt_5) +) + +(assert_return (invoke "f32.sqrt" (f32.const 2.0)) (f32.const 0x1.6a09e6p+0)) +(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)) +(assert_return (invoke "f32.sqrt" (f32.const 3.0)) (f32.const 0x1.bb67aep+0)) +(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)) +(assert_return (invoke "f32.sqrt" (f32.const 5.0)) (f32.const 0x1.1e377ap+1)) +(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)) +(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)) + +(assert_return (invoke "f64.sqrt" (f64.const 2.0)) (f64.const 0x1.6a09e667f3bcdp+0)) +(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)) +(assert_return (invoke "f64.sqrt" (f64.const 3.0)) (f64.const 0x1.bb67ae8584caap+0)) +(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)) +(assert_return (invoke "f64.sqrt" (f64.const 5.0)) (f64.const 0x1.1e3779b97f4a8p+1)) +(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)) +(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)) + +;; Compute the floating-point radix. +;; M. A. Malcom. Algorithms to reveal properties of floating-point arithmetic. +;; Communications of the ACM, 15(11):949-951, November 1972. +(module + (func $f32.compute_radix (param $0 f32) (param $1 f32) (result f32) + (loop $label$0 + (br_if $label$0 + (f32.eq + (f32.add + (f32.sub + (f32.add + (set_local $0 (f32.add (get_local $0) (get_local $0))) + (f32.const 1) + ) + (get_local $0) + ) + (f32.const -1) + ) + (f32.const 0) + ) + ) + ) + (loop $label$2 + (br_if $label$2 + (f32.ne + (f32.sub + (f32.sub + (f32.add + (get_local $0) + (set_local $1 (f32.add (get_local $1) (f32.const 1))) + ) + (get_local $0) + ) + (get_local $1) + ) + (f32.const 0) + ) + ) + ) + (get_local $1) + ) + (export "f32.compute_radix" $f32.compute_radix) + + (func $f64.compute_radix (param $0 f64) (param $1 f64) (result f64) + (loop $label$0 + (br_if $label$0 + (f64.eq + (f64.add + (f64.sub + (f64.add + (set_local $0 (f64.add (get_local $0) (get_local $0))) + (f64.const 1) + ) + (get_local $0) + ) + (f64.const -1) + ) + (f64.const 0) + ) + ) + ) + (loop $label$2 + (br_if $label$2 + (f64.ne + (f64.sub + (f64.sub + (f64.add + (get_local $0) + (set_local $1 (f64.add (get_local $1) (f64.const 1))) + ) + (get_local $0) + ) + (get_local $1) + ) + (f64.const 0) + ) + ) + ) + (get_local $1) + ) + (export "f64.compute_radix" $f64.compute_radix) +) + +(assert_return (invoke "f32.compute_radix" (f32.const 1.0) (f32.const 1.0)) (f32.const 2.0)) +(assert_return (invoke "f64.compute_radix" (f64.const 1.0) (f64.const 1.0)) (f64.const 2.0)) diff --git a/ml-proto/test/float_misc.wast b/ml-proto/test/float_misc.wast index 45c529c84c..c6698db0dd 100644 --- a/ml-proto/test/float_misc.wast +++ b/ml-proto/test/float_misc.wast @@ -6,8 +6,9 @@ ;; What this testsuite does test is that (a) the platform is basically IEEE 754 ;; rather than something else entirely, (b) it's configured correctly for ;; WebAssembly (rounding direction, exception masks, precision level, subnormal -;; mode, etc.), and (c) the WebAssembly implementation doesn't perform any -;; common value-changing optimizations. +;; mode, etc.), (c) the WebAssembly implementation doesn't perform any common +;; value-changing optimizations, and (d) that the WebAssembly implementation +;; doesn't exhibit any known implementation bugs. ;; ;; This file supplements f32.wast, f64.wast, f32_cmp.wast, and f64_cmp.wast with ;; additional single-instruction tests covering additional miscellaneous @@ -76,36 +77,36 @@ ) (assert_return (invoke "f32.add" (f32.const 1.1234567890) (f32.const 1.2345e-10)) (f32.const 1.123456789)) +(assert_return (invoke "f64.add" (f64.const 1.1234567890) (f64.const 1.2345e-10)) (f64.const 0x1.1f9add37c11f7p+0)) ;; Test adding the greatest value to 1.0 that rounds back to 1.0, and the ;; least that rounds to something greater. (assert_return (invoke "f32.add" (f32.const 1.0) (f32.const 0x1p-24)) (f32.const 0x1.0p+0)) (assert_return (invoke "f32.add" (f32.const 1.0) (f32.const 0x1.000002p-24)) (f32.const 0x1.000002p+0)) - -;; Computations that round differently in ties-to-odd mode. -(assert_return (invoke "f32.add" (f32.const 0x1p23) (f32.const 0x1p-1)) (f32.const 0x1p23)) -(assert_return (invoke "f32.add" (f32.const 0x1.000002p+23) (f32.const 0x1p-1)) (f32.const 0x1.000004p+23)) +(assert_return (invoke "f64.add" (f64.const 1.0) (f64.const 0x1p-53)) (f64.const 0x1.0p+0)) +(assert_return (invoke "f64.add" (f64.const 1.0) (f64.const 0x1.0000000000001p-53)) (f64.const 0x1.0000000000001p+0)) ;; Test that what some systems call signaling NaN behaves as a quiet NaN. (assert_return (invoke "f32.add" (f32.const nan:0x200000) (f32.const 1.0)) (f32.const nan:0x600000)) +(assert_return (invoke "f64.add" (f64.const nan:0x4000000000000) (f64.const 1.0)) (f64.const nan:0xc000000000000)) -(assert_return (invoke "f64.add" (f64.const 1.1234567890) (f64.const 1.2345e-10)) (f64.const 0x1.1f9add37c11f7p+0)) +;; Max subnornmal + min subnormal = min normal. +(assert_return (invoke "f32.add" (f32.const 0x1p-149) (f32.const 0x1.fffffcp-127)) (f32.const 0x1p-126)) +(assert_return (invoke "f64.add" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0.fffffffffffffp-1022)) (f64.const 0x1p-1022)) ;; Test for a case of double rounding, example from: ;; http://perso.ens-lyon.fr/jean-michel.muller/Handbook.html ;; section 3.3.1: A typical problem: "double rounding" +(assert_return (invoke "f32.add" (f32.const 0x1p+31) (f32.const 1024.25)) (f32.const 0x1.000008p+31)) (assert_return (invoke "f64.add" (f64.const 0x1p+63) (f64.const 1024.25)) (f64.const 0x1.0000000000001p+63)) ;; Test a case that was "tricky" on MMIX. ;; http://mmix.cs.hm.edu/bugs/bug_rounding.html (assert_return (invoke "f64.add" (f64.const -0x1p-1008) (f64.const 0x0.0000000001716p-1022)) (f64.const -0x1.fffffffffffffp-1009)) -;; Test adding the greatest value to 1.0 that rounds back to 1.0, and the -;; least that rounds to something greater. -(assert_return (invoke "f64.add" (f64.const 1.0) (f64.const 0x1p-53)) (f64.const 0x1.0p+0)) -(assert_return (invoke "f64.add" (f64.const 1.0) (f64.const 0x1.0000000000001p-53)) (f64.const 0x1.0000000000001p+0)) - ;; Computations that round differently in ties-to-odd mode. +(assert_return (invoke "f32.add" (f32.const 0x1p23) (f32.const 0x1p-1)) (f32.const 0x1p23)) +(assert_return (invoke "f32.add" (f32.const 0x1.000002p+23) (f32.const 0x1p-1)) (f32.const 0x1.000004p+23)) (assert_return (invoke "f64.add" (f64.const 0x1p52) (f64.const 0x1p-1)) (f64.const 0x1p52)) (assert_return (invoke "f64.add" (f64.const 0x1.0000000000001p+52) (f64.const 0x1p-1)) (f64.const 0x1.0000000000002p+52)) @@ -160,37 +161,43 @@ (assert_return (invoke "f64.add" (f64.const -0x1.ac627bd7cbf38p-198) (f64.const 0x1.2312e265b8d59p-990)) (f64.const -0x1.ac627bd7cbf38p-198)) ;; Computations that utilize the maximum exponent value to avoid overflow. -(assert_return (invoke "f64.add" (f64.const -0x1.397be95d10fddp+719) (f64.const -0x1.e13909d198d32p+1023)) (f64.const -0x1.e13909d198d32p+1023)) -(assert_return (invoke "f64.add" (f64.const -0x1.234a5a0412f41p+1023) (f64.const -0x1.53e9106c9367p+161)) (f64.const -0x1.234a5a0412f41p+1023)) -(assert_return (invoke "f64.add" (f64.const -0x1.a86bdb66cbb32p+562) (f64.const 0x1.d10ff29e1d6e8p+1023)) (f64.const 0x1.d10ff29e1d6e8p+1023)) -(assert_return (invoke "f64.add" (f64.const -0x1.dc295727a06e2p+1023) (f64.const 0x1.5e6979d7b24fp+485)) (f64.const -0x1.dc295727a06e2p+1023)) -(assert_return (invoke "f64.add" (f64.const -0x1.3ff7dee2861c6p-557) (f64.const 0x1.84a2c18238b4cp+1023)) (f64.const 0x1.84a2c18238b4cp+1023)) +(assert_return (invoke "f32.add" (f32.const 0x1.2b91ap+116) (f32.const 0x1.cbcd52p+127)) (f32.const 0x1.cbf2c4p+127)) +(assert_return (invoke "f32.add" (f32.const 0x1.96f392p+127) (f32.const -0x1.6b3fecp+107)) (f32.const 0x1.96f37cp+127)) +(assert_return (invoke "f32.add" (f32.const 0x1.132f1cp+118) (f32.const -0x1.63d632p+127)) (f32.const -0x1.634c9ap+127)) +(assert_return (invoke "f32.add" (f32.const -0x1.1dda64p+120) (f32.const -0x1.ef02ep+127)) (f32.const -0x1.f13e94p+127)) +(assert_return (invoke "f32.add" (f32.const -0x1.4ad8dap+127) (f32.const -0x1.eae082p+125)) (f32.const -0x1.c590fap+127)) +(assert_return (invoke "f64.add" (f64.const 0x1.017099f2a4b8bp+1023) (f64.const 0x1.1f63b28f05454p+981)) (f64.const 0x1.017099f2a5009p+1023)) +(assert_return (invoke "f64.add" (f64.const 0x1.d88b6c74984efp+1023) (f64.const 0x1.33b444775eabcp+990)) (f64.const 0x1.d88b6c7532291p+1023)) +(assert_return (invoke "f64.add" (f64.const -0x1.84576422fdf5p+1023) (f64.const 0x1.60ee6aa12fb9cp+1012)) (f64.const -0x1.842b4655a9cf1p+1023)) +(assert_return (invoke "f64.add" (f64.const -0x1.9aaace3e79f7dp+1001) (f64.const 0x1.e4068af295cb6p+1023)) (f64.const 0x1.e4068487ea926p+1023)) +(assert_return (invoke "f64.add" (f64.const 0x1.06cdae79f27b9p+1023) (f64.const -0x1.e05cb0c96f975p+991)) (f64.const 0x1.06cdae78121eep+1023)) ;; Computations that utilize the minimum exponent value. -(assert_return (invoke "f64.add" (f64.const -0x0.2d2c9b631ae47p-1022) (f64.const -0x0.8e173a51d11a7p-1022)) (f64.const -0x0.bb43d5b4ebfeep-1022)) -(assert_return (invoke "f64.add" (f64.const -0x0.ce7d534f2c7ep-1022) (f64.const -0x0.32f94dc4b7ee5p-1022)) (f64.const -0x1.0176a113e46c5p-1022)) -(assert_return (invoke "f64.add" (f64.const -0x1.44d9fb78bf5d3p-1021) (f64.const -0x0.02766a20d263fp-1022)) (f64.const -0x1.46153089288f2p-1021)) -(assert_return (invoke "f64.add" (f64.const 0x0.89e17f0fdc567p-1022) (f64.const -0x1.d9a93a01fd27dp-1021)) (f64.const -0x1.94b87a7a0efcap-1021)) -(assert_return (invoke "f64.add" (f64.const -0x0.3f3d1a052fa2bp-1022) (f64.const -0x1.4b78292c7d2adp-1021)) (f64.const -0x1.6b16b62f14fc2p-1021)) - -;; Test that what some systems call signaling NaN behaves as a quiet NaN. -(assert_return (invoke "f64.add" (f64.const nan:0x4000000000000) (f64.const 1.0)) (f64.const nan:0xc000000000000)) +(assert_return (invoke "f32.add" (f32.const 0x1.6a1a2p-127) (f32.const 0x1.378p-140)) (f32.const 0x1.6a23dcp-127)) +(assert_return (invoke "f32.add" (f32.const 0x1.28p-144) (f32.const -0x1p-148)) (f32.const 0x1.18p-144)) +(assert_return (invoke "f32.add" (f32.const -0x1p-146) (f32.const 0x1.c3cap-128)) (f32.const 0x1.c3c9cp-128)) +(assert_return (invoke "f32.add" (f32.const -0x1.4p-145) (f32.const 0x1.424052p-122)) (f32.const 0x1.42405p-122)) +(assert_return (invoke "f32.add" (f32.const 0x1.c5p-141) (f32.const -0x1.72f8p-135)) (f32.const -0x1.6be4p-135)) +(assert_return (invoke "f64.add" (f64.const 0x1.4774c681d1e21p-1022) (f64.const -0x1.271e58e9f58cap-1021)) (f64.const -0x1.06c7eb5219373p-1022)) +(assert_return (invoke "f64.add" (f64.const 0x1.10b3a75e31916p-1021) (f64.const -0x1.ffb82b0e868a7p-1021)) (f64.const -0x1.de090760a9f22p-1022)) +(assert_return (invoke "f64.add" (f64.const -0x0.6b58448b8098ap-1022) (f64.const -0x1.579796ed04cbep-1022)) (f64.const -0x1.c2efdb7885648p-1022)) +(assert_return (invoke "f64.add" (f64.const 0x1.9eb9e7baae8d1p-1020) (f64.const -0x1.d58e136f8c6eep-1020)) (f64.const -0x0.db50aed377874p-1022)) +(assert_return (invoke "f64.add" (f64.const -0x1.f1115deeafa0bp-1022) (f64.const 0x1.221b1c87dca29p-1022)) (f64.const -0x0.cef64166d2fe2p-1022)) + +;; Test an add of the second-greatest finite value with the distance to greatest +;; finite value. +(assert_return (invoke "f32.add" (f32.const 0x1.fffffcp+127) (f32.const 0x1p+104)) (f32.const 0x1.fffffep+127)) +(assert_return (invoke "f64.add" (f64.const 0x1.ffffffffffffep+1023) (f64.const 0x1p+971)) (f64.const 0x1.fffffffffffffp+1023)) ;; Test for a historic spreadsheet bug. ;; https://blogs.office.com/2007/09/25/calculation-issue-update/ (assert_return (invoke "f32.sub" (f32.const 65536.0) (f32.const 0x1p-37)) (f32.const 65536.0)) - -;; Test for a historic spreadsheet bug. -;; https://blogs.office.com/2007/09/25/calculation-issue-update/ (assert_return (invoke "f64.sub" (f64.const 65536.0) (f64.const 0x1p-37)) (f64.const 0x1.fffffffffffffp+15)) ;; Test subtracting the greatest value from 1.0 that rounds back to 1.0, and the ;; least that rounds to something less. (assert_return (invoke "f32.sub" (f32.const 1.0) (f32.const 0x1p-25)) (f32.const 0x1.0p+0)) (assert_return (invoke "f32.sub" (f32.const 1.0) (f32.const 0x1.000002p-25)) (f32.const 0x1.fffffep-1)) - -;; Test subtracting the greatest value from 1.0 that rounds back to 1.0, and the -;; least that rounds to something less. (assert_return (invoke "f64.sub" (f64.const 1.0) (f64.const 0x1p-54)) (f64.const 0x1.0p+0)) (assert_return (invoke "f64.sub" (f64.const 1.0) (f64.const 0x1.0000000000001p-54)) (f64.const 0x1.fffffffffffffp-1)) @@ -244,19 +251,26 @@ (assert_return (invoke "f64.sub" (f64.const 0x1.b60f9b2fbd9ecp-489) (f64.const -0x1.6f81c59ec5b8ep-694)) (f64.const 0x1.b60f9b2fbd9ecp-489)) (assert_return (invoke "f64.sub" (f64.const 0x1.5e423fe8571f4p-57) (f64.const 0x1.9624ed7c162dfp-618)) (f64.const 0x1.5e423fe8571f4p-57)) +;; pow(e, π) - π +;; https://xkcd.com/217 +(assert_return (invoke "f32.sub" (f32.const 0x1.724046p+4) (f32.const 0x1.921fb6p+1)) (f32.const 0x1.3ffc5p+4)) +(assert_return (invoke "f64.sub" (f64.const 0x1.724046eb0933ap+4) (f64.const 0x1.921fb54442d18p+1)) (f64.const 0x1.3ffc504280d97p+4)) + +;; https://www.cnet.com/news/googles-calculator-muffs-some-math-problems/ +(assert_return (invoke "f32.sub" (f32.const 2999999) (f32.const 2999998)) (f32.const 1.0)) +(assert_return (invoke "f32.sub" (f32.const 1999999) (f32.const 1999995)) (f32.const 4.0)) +(assert_return (invoke "f32.sub" (f32.const 1999999) (f32.const 1999993)) (f32.const 6.0)) +(assert_return (invoke "f32.sub" (f32.const 400002) (f32.const 400001)) (f32.const 1.0)) +(assert_return (invoke "f32.sub" (f32.const 400002) (f32.const 400000)) (f32.const 2.0)) +(assert_return (invoke "f64.sub" (f64.const 2999999999999999) (f64.const 2999999999999998)) (f64.const 1.0)) +(assert_return (invoke "f64.sub" (f64.const 1999999999999999) (f64.const 1999999999999995)) (f64.const 4.0)) +(assert_return (invoke "f64.sub" (f64.const 1999999999999999) (f64.const 1999999999999993)) (f64.const 6.0)) +(assert_return (invoke "f64.sub" (f64.const 400000000000002) (f64.const 400000000000001)) (f64.const 1.0)) +(assert_return (invoke "f64.sub" (f64.const 400000000000002) (f64.const 400000000000000)) (f64.const 2.0)) + (assert_return (invoke "f32.mul" (f32.const 1e15) (f32.const 1e15)) (f32.const 0x1.93e592p+99)) (assert_return (invoke "f32.mul" (f32.const 1e20) (f32.const 1e20)) (f32.const infinity)) (assert_return (invoke "f32.mul" (f32.const 1e25) (f32.const 1e25)) (f32.const infinity)) - -;; Test for a case of double rounding, example from: -;; http://perso.ens-lyon.fr/jean-michel.muller/Handbook.html -;; section 3.3.1: A typical problem: "double rounding" -(assert_return (invoke "f32.mul" (f32.const 1848874880.0) (f32.const 19954563072.0)) (f32.const 0x1.000002p+65)) - -;; Test for a historic spreadsheet bug. -;; http://www.joelonsoftware.com/items/2007/09/26b.html -(assert_return (invoke "f32.mul" (f32.const 77.1) (f32.const 850)) (f32.const 65535)) - (assert_return (invoke "f64.mul" (f64.const 1e15) (f64.const 1e15)) (f64.const 0x1.93e5939a08ceap+99)) (assert_return (invoke "f64.mul" (f64.const 1e20) (f64.const 1e20)) (f64.const 0x1.d6329f1c35ca5p+132)) (assert_return (invoke "f64.mul" (f64.const 1e25) (f64.const 1e25)) (f64.const 0x1.11b0ec57e649bp+166)) @@ -264,10 +278,12 @@ ;; Test for a case of double rounding, example from: ;; http://perso.ens-lyon.fr/jean-michel.muller/Handbook.html ;; section 3.3.1: A typical problem: "double rounding" +(assert_return (invoke "f32.mul" (f32.const 1848874880.0) (f32.const 19954563072.0)) (f32.const 0x1.000002p+65)) (assert_return (invoke "f64.mul" (f64.const 1848874847.0) (f64.const 19954562207.0)) (f64.const 3.6893488147419111424e+19)) ;; Test for a historic spreadsheet bug. ;; http://www.joelonsoftware.com/items/2007/09/26b.html +(assert_return (invoke "f32.mul" (f32.const 77.1) (f32.const 850)) (f32.const 65535)) (assert_return (invoke "f64.mul" (f64.const 77.1) (f64.const 850)) (f64.const 65534.99999999999272404)) ;; Computations that round differently in round-upward mode. @@ -327,12 +343,18 @@ (assert_return (invoke "f64.mul" (f64.const 0x1.e4d235961d543p-373) (f64.const 0x1.bc56f20ef9a48p-205)) (f64.const 0x1.a4c09efcb71d6p-577)) (assert_return (invoke "f64.mul" (f64.const -0x1.b9612e66faba8p+77) (f64.const 0x1.e2bc6aa782273p-348)) (f64.const -0x1.a026ea4f81db1p-270)) -;; Test the least value with a positive square. +;; Test the least positive value with a positive square. (assert_return (invoke "f32.mul" (f32.const 0x1p-75) (f32.const 0x1p-75)) (f32.const 0x0p+0)) (assert_return (invoke "f32.mul" (f32.const 0x1.000002p-75) (f32.const 0x1.000002p-75)) (f32.const 0x1p-149)) (assert_return (invoke "f64.mul" (f64.const 0x1.6a09e667f3bccp-538) (f64.const 0x1.6a09e667f3bccp-538)) (f64.const 0x0p+0)) (assert_return (invoke "f64.mul" (f64.const 0x1.6a09e667f3bcdp-538) (f64.const 0x1.6a09e667f3bcdp-538)) (f64.const 0x0.0000000000001p-1022)) +;; Test the greatest positive value with a finite square. +(assert_return (invoke "f32.mul" (f32.const 0x1.fffffep+63) (f32.const 0x1.fffffep+63)) (f32.const 0x1.fffffcp+127)) +(assert_return (invoke "f32.mul" (f32.const 0x1p+64) (f32.const 0x1p+64)) (f32.const infinity)) +(assert_return (invoke "f64.mul" (f64.const 0x1.fffffffffffffp+511) (f64.const 0x1.fffffffffffffp+511)) (f64.const 0x1.ffffffffffffep+1023)) +(assert_return (invoke "f64.mul" (f64.const 0x1p+512) (f64.const 0x1p+512)) (f64.const infinity)) + ;; Test MIN * EPSILON. ;; http://www.mpfr.org/mpfr-2.0.1/patch2 (assert_return (invoke "f32.mul" (f32.const 0x1p-126) (f32.const 0x1p-23)) (f32.const 0x1p-149)) @@ -343,18 +365,15 @@ (assert_return (invoke "f32.div" (f32.const 65536.0) (f32.const 0x1p-37)) (f32.const 0x1p+53)) (assert_return (invoke "f32.div" (f32.const 0x1.dcbf6ap+0) (f32.const 0x1.fffffep+127)) (f32.const 0x1.dcbf68p-128)) (assert_return (invoke "f32.div" (f32.const 4) (f32.const 3)) (f32.const 0x1.555556p+0)) - -;; Test for a historic hardware bug. -;; https://en.wikipedia.org/wiki/Pentium_FDIV_bug -(assert_return (invoke "f32.div" (f32.const 4195835) (f32.const 3145727)) (f32.const 0x1.557542p+0)) - (assert_return (invoke "f64.div" (f64.const 1.123456789) (f64.const 100)) (f64.const 0.01123456789)) (assert_return (invoke "f64.div" (f64.const 8391667.0) (f64.const 12582905.0)) (f64.const 0x1.55753f1d9ba27p-1)) (assert_return (invoke "f64.div" (f64.const 65536.0) (f64.const 0x1p-37)) (f64.const 0x1p+53)) +(assert_return (invoke "f64.div" (f64.const 0x1.dcbf6ap+0) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0.772fda8p-1022)) (assert_return (invoke "f64.div" (f64.const 4) (f64.const 3)) (f64.const 0x1.5555555555555p+0)) ;; Test for a historic hardware bug. ;; https://en.wikipedia.org/wiki/Pentium_FDIV_bug +(assert_return (invoke "f32.div" (f32.const 4195835) (f32.const 3145727)) (f32.const 0x1.557542p+0)) (assert_return (invoke "f64.div" (f64.const 4195835) (f64.const 3145727)) (f64.const 0x1.557541c7c6b43p+0)) ;; Computations that round differently in round-upward mode. @@ -409,6 +428,11 @@ (assert_return (invoke "f64.div" (f64.const 0x1.7057d6ab553cap-1005) (f64.const -0x1.2abf1e98660ebp+23)) (f64.const -0x0.04ee8d8ec01cdp-1022)) ;; Computations that round differently when div is mul by reciprocal. +(assert_return (invoke "f32.div" (f32.const 0x1.ada9aap+89) (f32.const 0x1.69884cp+42)) (f32.const 0x1.303e2ep+47)) +(assert_return (invoke "f32.div" (f32.const 0x1.8281c8p+90) (f32.const -0x1.62883cp+106)) (f32.const -0x1.17169cp-16)) +(assert_return (invoke "f32.div" (f32.const 0x1.5c6be2p+81) (f32.const 0x1.d01dfep-1)) (f32.const 0x1.805e32p+81)) +(assert_return (invoke "f32.div" (f32.const -0x1.bbd252p+19) (f32.const -0x1.fba95p+33)) (f32.const 0x1.bf9d56p-15)) +(assert_return (invoke "f32.div" (f32.const -0x1.0f41d6p-42) (f32.const -0x1.3f2dbep+56)) (f32.const 0x1.b320d8p-99)) (assert_return (invoke "f64.div" (f64.const 0x1.b2348a1c81899p+61) (f64.const -0x1.4a58aad903dd3p-861)) (f64.const -0x1.507c1e2a41b35p+922)) (assert_return (invoke "f64.div" (f64.const 0x1.23fa5137a918ap-130) (f64.const -0x1.7268db1951263p-521)) (f64.const -0x1.93965e0d896bep+390)) (assert_return (invoke "f64.div" (f64.const 0x1.dcb3915d82deep+669) (f64.const 0x1.50caaa1dc6b19p+638)) (f64.const 0x1.6a58ec814b09dp+31)) @@ -428,27 +452,50 @@ (assert_return (invoke "f64.div" (f64.const 0x1p-1022) (f64.const 0x0.fffffffffffffp-1022)) (f64.const 0x1.0000000000001p+0)) (assert_return (invoke "f64.div" (f64.const 0x0.fffffffffffffp-1022) (f64.const 0x1p-1022)) (f64.const 0x1.ffffffffffffep-1)) -;; Test the least value with a positive quotient with the maximum value. +;; Test the least positive value with a positive quotient with the maximum value. (assert_return (invoke "f32.div" (f32.const 0x1.fffffep-23) (f32.const 0x1.fffffep+127)) (f32.const 0x0p+0)) (assert_return (invoke "f32.div" (f32.const 0x1p-22) (f32.const 0x1.fffffep+127)) (f32.const 0x1p-149)) (assert_return (invoke "f64.div" (f64.const 0x1.fffffffffffffp-52) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0p+0)) (assert_return (invoke "f64.div" (f64.const 0x1p-51) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0.0000000000001p-1022)) -;; Test the least value with a finite reciprocal. +;; Test the least positive value with a finite reciprocal. (assert_return (invoke "f32.div" (f32.const 1.0) (f32.const 0x1p-128)) (f32.const infinity)) (assert_return (invoke "f32.div" (f32.const 1.0) (f32.const 0x1.000008p-128)) (f32.const 0x1.fffffp+127)) (assert_return (invoke "f64.div" (f64.const 1.0) (f64.const 0x0.4p-1022)) (f64.const infinity)) (assert_return (invoke "f64.div" (f64.const 1.0) (f64.const 0x0.4000000000001p-1022)) (f64.const 0x1.ffffffffffff8p+1023)) +;; Test the least positive value that has a subnormal reciprocal. +(assert_return (invoke "f32.div" (f32.const 1.0) (f32.const 0x1.000002p+126)) (f32.const 0x1.fffffcp-127)) +(assert_return (invoke "f32.div" (f32.const 1.0) (f32.const 0x1p+126)) (f32.const 0x1p-126)) +(assert_return (invoke "f64.div" (f64.const 1.0) (f64.const 0x1.0000000000001p+1022)) (f64.const 0x0.fffffffffffffp-1022)) +(assert_return (invoke "f64.div" (f64.const 1.0) (f64.const 0x1p+1022)) (f64.const 0x1p-1022)) + ;; Test the minimum positive normal number divided by the minimum positive ;; subnormal number. (assert_return (invoke "f32.div" (f32.const 0x1p-126) (f32.const 0x1p-149)) (f32.const 0x1p+23)) (assert_return (invoke "f64.div" (f64.const 0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1p+52)) +;; Test that the last binary digit of 1.0/3.0 is even in f32, +;; https://en.wikipedia.org/wiki/Single-precision_floating-point_format#Single-precision_examples +;; +;; and odd in f64, +;; https://en.wikipedia.org/wiki/Double-precision_floating-point_format#Double-precision_examples +;; +;; and that 1.0/3.0, 3.0/9.0, and 9.0/27.0 all agree. +;; http://www.netlib.org/paranoia +(assert_return (invoke "f32.div" (f32.const 0x1p+0) (f32.const 0x1.8p+1)) (f32.const 0x1.555556p-2)) +(assert_return (invoke "f32.div" (f32.const 0x3p+0) (f32.const 0x1.2p+3)) (f32.const 0x1.555556p-2)) +(assert_return (invoke "f32.div" (f32.const 0x1.2p+3) (f32.const 0x1.bp+4)) (f32.const 0x1.555556p-2)) +(assert_return (invoke "f64.div" (f64.const 0x1p+0) (f64.const 0x1.8p+1)) (f64.const 0x1.5555555555555p-2)) +(assert_return (invoke "f64.div" (f64.const 0x3p+0) (f64.const 0x1.2p+3)) (f64.const 0x1.5555555555555p-2)) +(assert_return (invoke "f64.div" (f64.const 0x1.2p+3) (f64.const 0x1.bp+4)) (f64.const 0x1.5555555555555p-2)) + ;; Test for bugs found in an early RISC-V implementation. ;; https://github.com/riscv/riscv-tests/pull/8 (assert_return (invoke "f32.sqrt" (f32.const 0x1.56p+7)) (f32.const 0x1.a2744cp+3)) (assert_return (invoke "f32.sqrt" (f32.const 0x1.594dfcp-23)) (f32.const 0x1.a4789cp-12)) +(assert_return (invoke "f64.sqrt" (f64.const 0x1.56p+7)) (f64.const 0x1.a2744ce9674f5p+3)) +(assert_return (invoke "f64.sqrt" (f64.const 0x1.594dfc70aa105p-23)) (f64.const 0x1.a4789c0e37f99p-12)) ;; Computations that round differently on x87. (assert_return (invoke "f64.sqrt" (f64.const 0x1.0263fcc94f259p-164)) (f64.const 0x1.0131485de579fp-82)) @@ -461,11 +508,6 @@ ;; https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52593 (assert_return (invoke "f64.sqrt" (f64.const 0x1.fffffffffffffp-1)) (f64.const 0x1.fffffffffffffp-1)) -;; Test for bugs found in an early RISC-V implementation. -;; https://github.com/riscv/riscv-tests/pull/8 -(assert_return (invoke "f64.sqrt" (f64.const 0x1.56p+7)) (f64.const 0x1.a2744ce9674f5p+3)) -(assert_return (invoke "f64.sqrt" (f64.const 0x1.594dfc70aa105p-23)) (f64.const 0x1.a4789c0e37f99p-12)) - ;; Computations that round differently in round-upward mode. (assert_return (invoke "f32.sqrt" (f32.const 0x1.098064p-3)) (f32.const 0x1.70b23p-2)) (assert_return (invoke "f32.sqrt" (f32.const 0x1.d9befp+100)) (f32.const 0x1.5c4052p+50)) @@ -509,13 +551,18 @@ (assert_return (invoke "f64.sqrt" (f64.const 0x1.e5522a741babep-276)) (f64.const 0x1.607ae2b6feb7dp-138)) (assert_return (invoke "f64.sqrt" (f64.const 0x1.4832badc0c061p+567)) (f64.const 0x1.99ec7934139b2p+283)) +;; Test the least greatest value with a sqrt that rounds to one. +(assert_return (invoke "f32.sqrt" (f32.const 0x1.000002p+0)) (f32.const 0x1p+0)) +(assert_return (invoke "f32.sqrt" (f32.const 0x1.000004p+0)) (f32.const 0x1.000002p+0)) +(assert_return (invoke "f64.sqrt" (f64.const 0x1.0000000000001p+0)) (f64.const 0x1p+0)) +(assert_return (invoke "f64.sqrt" (f64.const 0x1.0000000000002p+0)) (f64.const 0x1.0000000000001p+0)) + ;; Test that the bitwise floating point operators are bitwise on NaN. (assert_return (invoke "f32.abs" (f32.const nan)) (f32.const nan)) (assert_return (invoke "f32.abs" (f32.const -nan)) (f32.const nan)) (assert_return (invoke "f32.abs" (f32.const nan:0x0f1e2)) (f32.const nan:0x0f1e2)) (assert_return (invoke "f32.abs" (f32.const -nan:0x0f1e2)) (f32.const nan:0x0f1e2)) - (assert_return (invoke "f64.abs" (f64.const nan)) (f64.const nan)) (assert_return (invoke "f64.abs" (f64.const -nan)) (f64.const nan)) (assert_return (invoke "f64.abs" (f64.const nan:0x0f1e27a6b)) (f64.const nan:0x0f1e27a6b)) @@ -525,7 +572,6 @@ (assert_return (invoke "f32.neg" (f32.const -nan)) (f32.const nan)) (assert_return (invoke "f32.neg" (f32.const nan:0x0f1e2)) (f32.const -nan:0x0f1e2)) (assert_return (invoke "f32.neg" (f32.const -nan:0x0f1e2)) (f32.const nan:0x0f1e2)) - (assert_return (invoke "f64.neg" (f64.const nan)) (f64.const -nan)) (assert_return (invoke "f64.neg" (f64.const -nan)) (f64.const nan)) (assert_return (invoke "f64.neg" (f64.const nan:0x0f1e27a6b)) (f64.const -nan:0x0f1e27a6b)) @@ -539,7 +585,6 @@ (assert_return (invoke "f32.copysign" (f32.const nan:0x0f1e2) (f32.const -nan)) (f32.const -nan:0x0f1e2)) (assert_return (invoke "f32.copysign" (f32.const -nan:0x0f1e2) (f32.const nan)) (f32.const nan:0x0f1e2)) (assert_return (invoke "f32.copysign" (f32.const -nan:0x0f1e2) (f32.const -nan)) (f32.const -nan:0x0f1e2)) - (assert_return (invoke "f64.copysign" (f64.const nan) (f64.const nan)) (f64.const nan)) (assert_return (invoke "f64.copysign" (f64.const nan) (f64.const -nan)) (f64.const -nan)) (assert_return (invoke "f64.copysign" (f64.const -nan) (f64.const nan)) (f64.const nan)) @@ -552,19 +597,33 @@ ;; Test that ceil isn't implemented as adding 0.5 and rounding to nearest. (assert_return (invoke "f32.ceil" (f32.const 0x1.fffffep-1)) (f32.const 1.0)) (assert_return (invoke "f32.ceil" (f32.const 0x1p-126)) (f32.const 1.0)) - -;; Test that ceil isn't implemented as adding 0.5 and rounding to nearest. (assert_return (invoke "f64.ceil" (f64.const 0x1.fffffffffffffp-1)) (f64.const 1.0)) (assert_return (invoke "f64.ceil" (f64.const 0x1p-1022)) (f64.const 1.0)) +;; Test the maximum and minimum value for which ceil is not an identity operator. +(assert_return (invoke "f32.ceil" (f32.const 0x1.fffffep+22)) (f32.const 0x1p+23)) +(assert_return (invoke "f32.ceil" (f32.const -0x1.fffffep+22)) (f32.const -0x1.fffffcp+22)) +(assert_return (invoke "f64.ceil" (f64.const 0x1.fffffffffffffp+51)) (f64.const 0x1p+52)) +(assert_return (invoke "f64.ceil" (f64.const -0x1.fffffffffffffp+51)) (f64.const -0x1.ffffffffffffep+51)) + ;; Test that floor isn't implemented as subtracting 0.5 and rounding to nearest. (assert_return (invoke "f32.floor" (f32.const -0x1.fffffep-1)) (f32.const -1.0)) (assert_return (invoke "f32.floor" (f32.const -0x1p-126)) (f32.const -1.0)) - -;; Test that floor isn't implemented as subtracting 0.5 and rounding to nearest. (assert_return (invoke "f64.floor" (f64.const -0x1.fffffffffffffp-1)) (f64.const -1.0)) (assert_return (invoke "f64.floor" (f64.const -0x1p-1022)) (f64.const -1.0)) +;; Test the maximum and minimum value for which floor is not an identity operator. +(assert_return (invoke "f32.floor" (f32.const -0x1.fffffep+22)) (f32.const -0x1p+23)) +(assert_return (invoke "f32.floor" (f32.const 0x1.fffffep+22)) (f32.const 0x1.fffffcp+22)) +(assert_return (invoke "f64.floor" (f64.const -0x1.fffffffffffffp+51)) (f64.const -0x1p+52)) +(assert_return (invoke "f64.floor" (f64.const 0x1.fffffffffffffp+51)) (f64.const 0x1.ffffffffffffep+51)) + +;; Test the maximum and minimum value for which trunc is not an identity operator. +(assert_return (invoke "f32.trunc" (f32.const -0x1.fffffep+22)) (f32.const -0x1.fffffcp+22)) +(assert_return (invoke "f32.trunc" (f32.const 0x1.fffffep+22)) (f32.const 0x1.fffffcp+22)) +(assert_return (invoke "f64.trunc" (f64.const -0x1.fffffffffffffp+51)) (f64.const -0x1.ffffffffffffep+51)) +(assert_return (invoke "f64.trunc" (f64.const 0x1.fffffffffffffp+51)) (f64.const 0x1.ffffffffffffep+51)) + ;; Test that nearest isn't implemented naively. ;; http://blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1 ;; http://blog.frama-c.com/index.php?post/2013/05/04/nearbyintf3 @@ -572,7 +631,6 @@ (assert_return (invoke "f32.nearest" (f32.const 0x1.000004p+23)) (f32.const 0x1.000004p+23)) (assert_return (invoke "f32.nearest" (f32.const 0x1.fffffep-2)) (f32.const 0.0)) (assert_return (invoke "f32.nearest" (f32.const 0x1.fffffep+47)) (f32.const 0x1.fffffep+47)) - (assert_return (invoke "f64.nearest" (f64.const 0x1.0000000000001p+52)) (f64.const 0x1.0000000000001p+52)) (assert_return (invoke "f64.nearest" (f64.const 0x1.0000000000002p+52)) (f64.const 0x1.0000000000002p+52)) (assert_return (invoke "f64.nearest" (f64.const 0x1.fffffffffffffp-2)) (f64.const 0.0)) @@ -587,6 +645,12 @@ (assert_return (invoke "f64.nearest" (f64.const -4.5)) (f64.const -4.0)) (assert_return (invoke "f64.nearest" (f64.const -3.5)) (f64.const -4.0)) +;; Test the maximum and minimum value for which nearest is not an identity operator. +(assert_return (invoke "f32.nearest" (f32.const -0x1.fffffep+22)) (f32.const -0x1p+23)) +(assert_return (invoke "f32.nearest" (f32.const 0x1.fffffep+22)) (f32.const 0x1p+23)) +(assert_return (invoke "f64.nearest" (f64.const -0x1.fffffffffffffp+51)) (f64.const -0x1p+52)) +(assert_return (invoke "f64.nearest" (f64.const 0x1.fffffffffffffp+51)) (f64.const 0x1p+52)) + ;; Test that min and max behave properly with signaling NaNs. (assert_return (invoke "f32.min" (f32.const 0.0) (f32.const nan:0x200000)) (f32.const nan:0x600000)) (assert_return (invoke "f32.min" (f32.const nan:0x200000) (f32.const 0.0)) (f32.const nan:0x600000)) diff --git a/ml-proto/test/i32.wast b/ml-proto/test/i32.wast index 6f7e6ddf2b..f77dff24de 100644 --- a/ml-proto/test/i32.wast +++ b/ml-proto/test/i32.wast @@ -242,12 +242,16 @@ (assert_return (invoke "rotl" (i32.const 0xabcd9876) (i32.const 1)) (i32.const 0x579b30ed)) (assert_return (invoke "rotl" (i32.const 0x00008000) (i32.const 37)) (i32.const 0x00100000)) (assert_return (invoke "rotl" (i32.const 0x769abcdf) (i32.const 0x8000000d)) (i32.const 0x579beed3)) +(assert_return (invoke "rotl" (i32.const 1) (i32.const 31)) (i32.const 0x80000000)) +(assert_return (invoke "rotl" (i32.const 0x80000000) (i32.const 1)) (i32.const 1)) (assert_return (invoke "rotr" (i32.const 0xb0c1d2e3) (i32.const 0x0005)) (i32.const 0x1d860e97)) (assert_return (invoke "rotr" (i32.const 0xb0c1d2e3) (i32.const 0xff05)) (i32.const 0x1d860e97)) (assert_return (invoke "rotr" (i32.const 0xff00cc00) (i32.const 1)) (i32.const 0x7f806600)) (assert_return (invoke "rotr" (i32.const 0x00080000) (i32.const 4)) (i32.const 0x00008000)) (assert_return (invoke "rotr" (i32.const 0x769abcdf) (i32.const 0xffffffed)) (i32.const 0xe6fbb4d5)) +(assert_return (invoke "rotr" (i32.const 1) (i32.const 1)) (i32.const 0x80000000)) +(assert_return (invoke "rotr" (i32.const 0x80000000) (i32.const 31)) (i32.const 1)) (assert_return (invoke "clz" (i32.const 0xffffffff)) (i32.const 0)) (assert_return (invoke "clz" (i32.const 0)) (i32.const 32)) @@ -256,17 +260,20 @@ (assert_return (invoke "clz" (i32.const 0x80000000)) (i32.const 0)) (assert_return (invoke "clz" (i32.const 1)) (i32.const 31)) (assert_return (invoke "clz" (i32.const 2)) (i32.const 30)) +(assert_return (invoke "clz" (i32.const 0x7fffffff)) (i32.const 1)) (assert_return (invoke "ctz" (i32.const -1)) (i32.const 0)) (assert_return (invoke "ctz" (i32.const 0)) (i32.const 32)) (assert_return (invoke "ctz" (i32.const 0x00008000)) (i32.const 15)) (assert_return (invoke "ctz" (i32.const 0x00010000)) (i32.const 16)) (assert_return (invoke "ctz" (i32.const 0x80000000)) (i32.const 31)) +(assert_return (invoke "ctz" (i32.const 0x7fffffff)) (i32.const 0)) (assert_return (invoke "popcnt" (i32.const -1)) (i32.const 32)) (assert_return (invoke "popcnt" (i32.const 0)) (i32.const 0)) (assert_return (invoke "popcnt" (i32.const 0x00008000)) (i32.const 1)) (assert_return (invoke "popcnt" (i32.const 0x80008000)) (i32.const 2)) +(assert_return (invoke "popcnt" (i32.const 0x7fffffff)) (i32.const 31)) (assert_return (invoke "popcnt" (i32.const 0xAAAAAAAA)) (i32.const 16)) (assert_return (invoke "popcnt" (i32.const 0x55555555)) (i32.const 16)) (assert_return (invoke "popcnt" (i32.const 0xDEADBEEF)) (i32.const 24)) @@ -274,6 +281,7 @@ (assert_return (invoke "eqz" (i32.const 0)) (i32.const 1)) (assert_return (invoke "eqz" (i32.const 1)) (i32.const 0)) (assert_return (invoke "eqz" (i32.const 0x80000000)) (i32.const 0)) +(assert_return (invoke "eqz" (i32.const 0x7fffffff)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 0) (i32.const 0)) (i32.const 1)) (assert_return (invoke "eq" (i32.const 1) (i32.const 1)) (i32.const 1)) @@ -282,9 +290,13 @@ (assert_return (invoke "eq" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1)) (assert_return (invoke "eq" (i32.const -1) (i32.const -1)) (i32.const 1)) (assert_return (invoke "eq" (i32.const 1) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 1)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 0x80000000) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 0x80000000)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 0x80000000) (i32.const -1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const -1) (i32.const 0x80000000)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0)) (assert_return (invoke "ne" (i32.const 0) (i32.const 0)) (i32.const 0)) (assert_return (invoke "ne" (i32.const 1) (i32.const 1)) (i32.const 0)) @@ -293,9 +305,13 @@ (assert_return (invoke "ne" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 0)) (assert_return (invoke "ne" (i32.const -1) (i32.const -1)) (i32.const 0)) (assert_return (invoke "ne" (i32.const 1) (i32.const 0)) (i32.const 1)) +(assert_return (invoke "ne" (i32.const 0) (i32.const 1)) (i32.const 1)) (assert_return (invoke "ne" (i32.const 0x80000000) (i32.const 0)) (i32.const 1)) +(assert_return (invoke "ne" (i32.const 0) (i32.const 0x80000000)) (i32.const 1)) (assert_return (invoke "ne" (i32.const 0x80000000) (i32.const -1)) (i32.const 1)) +(assert_return (invoke "ne" (i32.const -1) (i32.const 0x80000000)) (i32.const 1)) (assert_return (invoke "ne" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1)) +(assert_return (invoke "ne" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 1)) (assert_return (invoke "lt_s" (i32.const 0) (i32.const 0)) (i32.const 0)) (assert_return (invoke "lt_s" (i32.const 1) (i32.const 1)) (i32.const 0)) diff --git a/ml-proto/test/i64.wast b/ml-proto/test/i64.wast index d6b7829a42..f8b9621839 100644 --- a/ml-proto/test/i64.wast +++ b/ml-proto/test/i64.wast @@ -243,6 +243,8 @@ (assert_return (invoke "rotl" (i64.const -1) (i64.const 1)) (i64.const -1)) (assert_return (invoke "rotl" (i64.const 0xabd1234ef567809c) (i64.const 63)) (i64.const 0x55e891a77ab3c04e)) (assert_return (invoke "rotl" (i64.const 0xabd1234ef567809c) (i64.const 0x800000000000003f)) (i64.const 0x55e891a77ab3c04e)) +(assert_return (invoke "rotl" (i64.const 1) (i64.const 63)) (i64.const 0x8000000000000000)) +(assert_return (invoke "rotl" (i64.const 0x8000000000000000) (i64.const 1)) (i64.const 1)) (assert_return (invoke "rotr" (i64.const 1) (i64.const 1)) (i64.const 0x8000000000000000)) (assert_return (invoke "rotr" (i64.const 1) (i64.const 0)) (i64.const 1)) @@ -250,6 +252,8 @@ (assert_return (invoke "rotr" (i64.const 0xabcd1234ef567809) (i64.const 53)) (i64.const 0x6891a77ab3c04d5e)) (assert_return (invoke "rotr" (i64.const 0xabcd1234ef567809) (i64.const 0x35)) (i64.const 0x6891a77ab3c04d5e)) (assert_return (invoke "rotr" (i64.const 0xabcd1234ef567809) (i64.const 0xf5)) (i64.const 0x6891a77ab3c04d5e)) +(assert_return (invoke "rotr" (i64.const 1) (i64.const 1)) (i64.const 0x8000000000000000)) +(assert_return (invoke "rotr" (i64.const 0x8000000000000000) (i64.const 63)) (i64.const 1)) (assert_return (invoke "clz" (i64.const 0xffffffffffffffff)) (i64.const 0)) (assert_return (invoke "clz" (i64.const 0)) (i64.const 64)) @@ -258,17 +262,20 @@ (assert_return (invoke "clz" (i64.const 0x8000000000000000)) (i64.const 0)) (assert_return (invoke "clz" (i64.const 1)) (i64.const 63)) (assert_return (invoke "clz" (i64.const 2)) (i64.const 62)) +(assert_return (invoke "clz" (i64.const 0x7fffffffffffffff)) (i64.const 1)) (assert_return (invoke "ctz" (i64.const -1)) (i64.const 0)) (assert_return (invoke "ctz" (i64.const 0)) (i64.const 64)) (assert_return (invoke "ctz" (i64.const 0x00008000)) (i64.const 15)) (assert_return (invoke "ctz" (i64.const 0x00010000)) (i64.const 16)) (assert_return (invoke "ctz" (i64.const 0x8000000000000000)) (i64.const 63)) +(assert_return (invoke "ctz" (i64.const 0x7fffffffffffffff)) (i64.const 0)) (assert_return (invoke "popcnt" (i64.const -1)) (i64.const 64)) (assert_return (invoke "popcnt" (i64.const 0)) (i64.const 0)) (assert_return (invoke "popcnt" (i64.const 0x00008000)) (i64.const 1)) (assert_return (invoke "popcnt" (i64.const 0x8000800080008000)) (i64.const 4)) +(assert_return (invoke "popcnt" (i64.const 0x7fffffffffffffff)) (i64.const 63)) (assert_return (invoke "popcnt" (i64.const 0xAAAAAAAA55555555)) (i64.const 32)) (assert_return (invoke "popcnt" (i64.const 0x99999999AAAAAAAA)) (i64.const 32)) (assert_return (invoke "popcnt" (i64.const 0xDEADBEEFDEADBEEF)) (i64.const 48)) @@ -276,6 +283,7 @@ (assert_return (invoke "eqz" (i64.const 0)) (i32.const 1)) (assert_return (invoke "eqz" (i64.const 1)) (i32.const 0)) (assert_return (invoke "eqz" (i64.const 0x8000000000000000)) (i32.const 0)) +(assert_return (invoke "eqz" (i64.const 0x7fffffffffffffff)) (i32.const 0)) (assert_return (invoke "eq" (i64.const 0) (i64.const 0)) (i32.const 1)) (assert_return (invoke "eq" (i64.const 1) (i64.const 1)) (i32.const 1)) @@ -284,9 +292,13 @@ (assert_return (invoke "eq" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 1)) (assert_return (invoke "eq" (i64.const -1) (i64.const -1)) (i32.const 1)) (assert_return (invoke "eq" (i64.const 1) (i64.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i64.const 0) (i64.const 1)) (i32.const 0)) (assert_return (invoke "eq" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 0)) (assert_return (invoke "eq" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 0)) +(assert_return (invoke "eq" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 0)) (assert_return (invoke "eq" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 0)) +(assert_return (invoke "eq" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 0)) (assert_return (invoke "ne" (i64.const 0) (i64.const 0)) (i32.const 0)) (assert_return (invoke "ne" (i64.const 1) (i64.const 1)) (i32.const 0)) @@ -295,9 +307,13 @@ (assert_return (invoke "ne" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 0)) (assert_return (invoke "ne" (i64.const -1) (i64.const -1)) (i32.const 0)) (assert_return (invoke "ne" (i64.const 1) (i64.const 0)) (i32.const 1)) +(assert_return (invoke "ne" (i64.const 0) (i64.const 1)) (i32.const 1)) (assert_return (invoke "ne" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 1)) +(assert_return (invoke "ne" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 1)) (assert_return (invoke "ne" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 1)) +(assert_return (invoke "ne" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 1)) (assert_return (invoke "ne" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 1)) +(assert_return (invoke "ne" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 1)) (assert_return (invoke "lt_s" (i64.const 0) (i64.const 0)) (i32.const 0)) (assert_return (invoke "lt_s" (i64.const 1) (i64.const 1)) (i32.const 0)) diff --git a/ml-proto/test/memory_redundancy.wast b/ml-proto/test/memory_redundancy.wast index 9053e04a48..fe0607f6e9 100644 --- a/ml-proto/test/memory_redundancy.wast +++ b/ml-proto/test/memory_redundancy.wast @@ -22,9 +22,12 @@ (export "test_redundant_load" $test_redundant_load) (func $test_redundant_load (result i32) - (i32.load (i32.const 8)) - (f32.store (i32.const 5) (f32.const -0.0)) - (i32.load (i32.const 8)) + (local $t i32) + (local $s i32) + (set_local $t (i32.load (i32.const 8))) + (i32.store (i32.const 5) (i32.const 0x80000000)) + (set_local $s (i32.load (i32.const 8))) + (i32.add (get_local $t) (get_local $s)) ) (export "test_dead_store" $test_dead_store) From ee4356aec4a0bfbbb79cbdc7666265f6e193ce4f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 8 Jul 2016 09:26:42 -0700 Subject: [PATCH 02/13] Test floating-point sub around normal/subnormal boundaries. --- ml-proto/test/float_misc.wast | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ml-proto/test/float_misc.wast b/ml-proto/test/float_misc.wast index c6698db0dd..b3cefd6de2 100644 --- a/ml-proto/test/float_misc.wast +++ b/ml-proto/test/float_misc.wast @@ -268,6 +268,14 @@ (assert_return (invoke "f64.sub" (f64.const 400000000000002) (f64.const 400000000000001)) (f64.const 1.0)) (assert_return (invoke "f64.sub" (f64.const 400000000000002) (f64.const 400000000000000)) (f64.const 2.0)) +;; Min normal - min subnormal = max subnornmal. +(assert_return (invoke "f32.sub" (f32.const 0x1p-126) (f32.const 0x1p-149)) (f32.const 0x1.fffffcp-127)) +(assert_return (invoke "f64.sub" (f64.const 0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x0.fffffffffffffp-1022)) + +;; Min normal - max subnormal = min subnornmal. +(assert_return (invoke "f32.sub" (f32.const 0x1p-126) (f32.const 0x1.fffffcp-127)) (f32.const 0x1p-149)) +(assert_return (invoke "f64.sub" (f64.const 0x1p-1022) (f64.const 0x0.fffffffffffffp-1022)) (f64.const 0x0.0000000000001p-1022)) + (assert_return (invoke "f32.mul" (f32.const 1e15) (f32.const 1e15)) (f32.const 0x1.93e592p+99)) (assert_return (invoke "f32.mul" (f32.const 1e20) (f32.const 1e20)) (f32.const infinity)) (assert_return (invoke "f32.mul" (f32.const 1e25) (f32.const 1e25)) (f32.const infinity)) From 7a12dd071d5c2dc07e57a5e13093184570949504 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 8 Jul 2016 09:34:03 -0700 Subject: [PATCH 03/13] Add a few comments. --- ml-proto/test/float_misc.wast | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ml-proto/test/float_misc.wast b/ml-proto/test/float_misc.wast index b3cefd6de2..b01fb37f4d 100644 --- a/ml-proto/test/float_misc.wast +++ b/ml-proto/test/float_misc.wast @@ -76,6 +76,7 @@ (export "f64.max" $f64.max) ) +;; Miscellaneous values. (assert_return (invoke "f32.add" (f32.const 1.1234567890) (f32.const 1.2345e-10)) (f32.const 1.123456789)) (assert_return (invoke "f64.add" (f64.const 1.1234567890) (f64.const 1.2345e-10)) (f64.const 0x1.1f9add37c11f7p+0)) @@ -276,6 +277,7 @@ (assert_return (invoke "f32.sub" (f32.const 0x1p-126) (f32.const 0x1.fffffcp-127)) (f32.const 0x1p-149)) (assert_return (invoke "f64.sub" (f64.const 0x1p-1022) (f64.const 0x0.fffffffffffffp-1022)) (f64.const 0x0.0000000000001p-1022)) +;; Miscellaneous values. (assert_return (invoke "f32.mul" (f32.const 1e15) (f32.const 1e15)) (f32.const 0x1.93e592p+99)) (assert_return (invoke "f32.mul" (f32.const 1e20) (f32.const 1e20)) (f32.const infinity)) (assert_return (invoke "f32.mul" (f32.const 1e25) (f32.const 1e25)) (f32.const infinity)) @@ -368,6 +370,7 @@ (assert_return (invoke "f32.mul" (f32.const 0x1p-126) (f32.const 0x1p-23)) (f32.const 0x1p-149)) (assert_return (invoke "f64.mul" (f64.const 0x1p-1022) (f64.const 0x1p-52)) (f64.const 0x0.0000000000001p-1022)) +;; Miscellaneous values. (assert_return (invoke "f32.div" (f32.const 1.123456789) (f32.const 100)) (f32.const 0x1.702264p-7)) (assert_return (invoke "f32.div" (f32.const 8391667.0) (f32.const 12582905.0)) (f32.const 0x1.55754p-1)) (assert_return (invoke "f32.div" (f32.const 65536.0) (f32.const 0x1p-37)) (f32.const 0x1p+53)) From 3f5a236d35926abc04658ee4c1cdf157e2a703cd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 15 Jul 2016 12:50:13 -0700 Subject: [PATCH 04/13] Test that (x - 1) * y + y is not optimized to x * y. --- ml-proto/test/float_exprs.wast | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ml-proto/test/float_exprs.wast b/ml-proto/test/float_exprs.wast index db20472de5..86105eea64 100644 --- a/ml-proto/test/float_exprs.wast +++ b/ml-proto/test/float_exprs.wast @@ -2016,3 +2016,19 @@ (assert_return (invoke "f32.compute_radix" (f32.const 1.0) (f32.const 1.0)) (f32.const 2.0)) (assert_return (invoke "f64.compute_radix" (f64.const 1.0) (f64.const 1.0)) (f64.const 2.0)) + +;; Test that (x - 1) * y + y is not optimized to x * y. +;; http://blog.frama-c.com/index.php?post/2013/05/14/Contrarianism + +(module + (func $f32.no_fold_sub1_mul_add (param $x f32) (param $y f32) (result f32) + (f32.add (f32.mul (f32.sub (get_local $x) (f32.const 1.0)) (get_local $y)) (get_local $y))) + (export "f32.no_fold_sub1_mul_add" $f32.no_fold_sub1_mul_add) + + (func $f64.no_fold_sub1_mul_add (param $x f64) (param $y f64) (result f64) + (f64.add (f64.mul (f64.sub (get_local $x) (f64.const 1.0)) (get_local $y)) (get_local $y))) + (export "f64.no_fold_sub1_mul_add" $f64.no_fold_sub1_mul_add) +) + +(assert_return (invoke "f32.no_fold_sub1_mul_add" (f32.const 0x1p-32) (f32.const 1.0)) (f32.const 0x0p+0)) +(assert_return (invoke "f64.no_fold_sub1_mul_add" (f64.const 0x1p-64) (f64.const 1.0)) (f64.const 0x0p+0)) From 0c17f8294768b7268131aba4fcb5436051845ebd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 15 Jul 2016 12:50:20 -0700 Subject: [PATCH 05/13] Test that x+z >= y+z is not optimized to x >= y (monotonicity). --- ml-proto/test/float_exprs.wast | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ml-proto/test/float_exprs.wast b/ml-proto/test/float_exprs.wast index 86105eea64..4e639b7983 100644 --- a/ml-proto/test/float_exprs.wast +++ b/ml-proto/test/float_exprs.wast @@ -2032,3 +2032,29 @@ (assert_return (invoke "f32.no_fold_sub1_mul_add" (f32.const 0x1p-32) (f32.const 1.0)) (f32.const 0x0p+0)) (assert_return (invoke "f64.no_fold_sub1_mul_add" (f64.const 0x1p-64) (f64.const 1.0)) (f64.const 0x0p+0)) + +;; Test that x+z >= y+z is not optimized to x >= y (monotonicity). +;; http://cs.nyu.edu/courses/spring13/CSCI-UA.0201-003/lecture6.pdf + +(module + (func $f32.no_fold_add_le_monotonicity (param $x f32) (param $y f32) (param $z f32) (result i32) + (f32.le (f32.add (get_local $x) (get_local $z)) (f32.add (get_local $y) (get_local $z)))) + (export "f32.no_fold_add_le_monotonicity" $f32.no_fold_add_le_monotonicity) + + (func $f32.no_fold_add_ge_monotonicity (param $x f32) (param $y f32) (param $z f32) (result i32) + (f32.ge (f32.add (get_local $x) (get_local $z)) (f32.add (get_local $y) (get_local $z)))) + (export "f32.no_fold_add_ge_monotonicity" $f32.no_fold_add_ge_monotonicity) + + (func $f64.no_fold_add_le_monotonicity (param $x f64) (param $y f64) (param $z f64) (result i32) + (f64.le (f64.add (get_local $x) (get_local $z)) (f64.add (get_local $y) (get_local $z)))) + (export "f64.no_fold_add_le_monotonicity" $f64.no_fold_add_le_monotonicity) + + (func $f64.no_fold_add_ge_monotonicity (param $x f64) (param $y f64) (param $z f64) (result i32) + (f64.ge (f64.add (get_local $x) (get_local $z)) (f64.add (get_local $y) (get_local $z)))) + (export "f64.no_fold_add_ge_monotonicity" $f64.no_fold_add_ge_monotonicity) +) + +(assert_return (invoke "f32.no_fold_add_le_monotonicity" (f32.const 0.0) (f32.const 0.0) (f32.const nan)) (i32.const 0)) +(assert_return (invoke "f32.no_fold_add_le_monotonicity" (f32.const infinity) (f32.const -infinity) (f32.const infinity)) (i32.const 0)) +(assert_return (invoke "f64.no_fold_add_le_monotonicity" (f64.const 0.0) (f64.const 0.0) (f64.const nan)) (i32.const 0)) +(assert_return (invoke "f64.no_fold_add_le_monotonicity" (f64.const infinity) (f64.const -infinity) (f64.const infinity)) (i32.const 0)) From 371f47423507351362a387ef08870ca3c473d117 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 15 Jul 2016 12:50:23 -0700 Subject: [PATCH 06/13] Test that !(x < y) and friends are not optimized to x >= y and friends. --- ml-proto/test/float_exprs.wast | 45 ++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/ml-proto/test/float_exprs.wast b/ml-proto/test/float_exprs.wast index 4e639b7983..0397f47c17 100644 --- a/ml-proto/test/float_exprs.wast +++ b/ml-proto/test/float_exprs.wast @@ -2058,3 +2058,48 @@ (assert_return (invoke "f32.no_fold_add_le_monotonicity" (f32.const infinity) (f32.const -infinity) (f32.const infinity)) (i32.const 0)) (assert_return (invoke "f64.no_fold_add_le_monotonicity" (f64.const 0.0) (f64.const 0.0) (f64.const nan)) (i32.const 0)) (assert_return (invoke "f64.no_fold_add_le_monotonicity" (f64.const infinity) (f64.const -infinity) (f64.const infinity)) (i32.const 0)) + +;; Test that !(x < y) and friends are not optimized to x >= y and friends. + +(module + (func $f32.not_lt (param $x f32) (param $y f32) (result i32) + (i32.eqz (f32.lt (get_local $x) (get_local $y)))) + (export "f32.not_lt" $f32.not_lt) + + (func $f32.not_le (param $x f32) (param $y f32) (result i32) + (i32.eqz (f32.le (get_local $x) (get_local $y)))) + (export "f32.not_le" $f32.not_le) + + (func $f32.not_gt (param $x f32) (param $y f32) (result i32) + (i32.eqz (f32.gt (get_local $x) (get_local $y)))) + (export "f32.not_gt" $f32.not_gt) + + (func $f32.not_ge (param $x f32) (param $y f32) (result i32) + (i32.eqz (f32.ge (get_local $x) (get_local $y)))) + (export "f32.not_ge" $f32.not_ge) + + (func $f64.not_lt (param $x f64) (param $y f64) (result i32) + (i32.eqz (f64.lt (get_local $x) (get_local $y)))) + (export "f64.not_lt" $f64.not_lt) + + (func $f64.not_le (param $x f64) (param $y f64) (result i32) + (i32.eqz (f64.le (get_local $x) (get_local $y)))) + (export "f64.not_le" $f64.not_le) + + (func $f64.not_gt (param $x f64) (param $y f64) (result i32) + (i32.eqz (f64.gt (get_local $x) (get_local $y)))) + (export "f64.not_gt" $f64.not_gt) + + (func $f64.not_ge (param $x f64) (param $y f64) (result i32) + (i32.eqz (f64.ge (get_local $x) (get_local $y)))) + (export "f64.not_ge" $f64.not_ge) +) + +(assert_return (invoke "f32.not_lt" (f32.const nan) (f32.const 0.0)) (i32.const 1)) +(assert_return (invoke "f32.not_le" (f32.const nan) (f32.const 0.0)) (i32.const 1)) +(assert_return (invoke "f32.not_gt" (f32.const nan) (f32.const 0.0)) (i32.const 1)) +(assert_return (invoke "f32.not_ge" (f32.const nan) (f32.const 0.0)) (i32.const 1)) +(assert_return (invoke "f64.not_lt" (f64.const nan) (f64.const 0.0)) (i32.const 1)) +(assert_return (invoke "f64.not_le" (f64.const nan) (f64.const 0.0)) (i32.const 1)) +(assert_return (invoke "f64.not_gt" (f64.const nan) (f64.const 0.0)) (i32.const 1)) +(assert_return (invoke "f64.not_ge" (f64.const nan) (f64.const 0.0)) (i32.const 1)) From 9c7efdfdb24f7a3c539b2889545e4a700325a2ed Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 15 Jul 2016 12:50:26 -0700 Subject: [PATCH 07/13] Test that a method for approximating a "machine epsilon" produces the expected approximation. --- ml-proto/test/float_exprs.wast | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ml-proto/test/float_exprs.wast b/ml-proto/test/float_exprs.wast index 0397f47c17..3143484f85 100644 --- a/ml-proto/test/float_exprs.wast +++ b/ml-proto/test/float_exprs.wast @@ -2103,3 +2103,20 @@ (assert_return (invoke "f64.not_le" (f64.const nan) (f64.const 0.0)) (i32.const 1)) (assert_return (invoke "f64.not_gt" (f64.const nan) (f64.const 0.0)) (i32.const 1)) (assert_return (invoke "f64.not_ge" (f64.const nan) (f64.const 0.0)) (i32.const 1)) + +;; Test that a method for approximating a "machine epsilon" produces the expected +;; approximation. +;; http://blogs.mathworks.com/cleve/2014/07/07/floating-point-numbers/#24cb4f4d-b8a9-4c19-b22b-9d2a9f7f3812 + +(module + (func $f32.epsilon (result f32) + (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))))) + (export "f32.epsilon" $f32.epsilon) + + (func $f64.epsilon (result f64) + (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))))) + (export "f64.epsilon" $f64.epsilon) +) + +(assert_return (invoke "f32.epsilon") (f32.const -0x1p-23)) +(assert_return (invoke "f64.epsilon") (f64.const 0x1p-52)) From 9357d7ae2c44fbdb635dd10d857c99c89e3e33af Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 15 Jul 2016 12:50:28 -0700 Subject: [PATCH 08/13] Clarify a comment. --- ml-proto/test/float_exprs.wast | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ml-proto/test/float_exprs.wast b/ml-proto/test/float_exprs.wast index 3143484f85..0c11b9b3bb 100644 --- a/ml-proto/test/float_exprs.wast +++ b/ml-proto/test/float_exprs.wast @@ -1871,7 +1871,8 @@ (assert_return (invoke "f32.no_distribute_exact" (f32.const -0.0)) (f32.const 0.0)) (assert_return (invoke "f64.no_distribute_exact" (f64.const -0.0)) (f64.const 0.0)) -;; Test various approximations of sqrt(2), sqrt(3), and sqrt(5). +;; Test that various approximations of sqrt(2), sqrt(3), and sqrt(5) compute the +;; expected approximation. ;; https://xkcd.com/1047/ (module (func $f32.sqrt (param f32) (result f32) From b70cd1750b6284a0033a4b8107b4d760dcb9adf9 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 15 Jul 2016 12:50:31 -0700 Subject: [PATCH 09/13] Test that floating-point numbers do not form a trichotomy. --- ml-proto/test/float_exprs.wast | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/ml-proto/test/float_exprs.wast b/ml-proto/test/float_exprs.wast index 0c11b9b3bb..5c4a6e1b69 100644 --- a/ml-proto/test/float_exprs.wast +++ b/ml-proto/test/float_exprs.wast @@ -2121,3 +2121,43 @@ (assert_return (invoke "f32.epsilon") (f32.const -0x1p-23)) (assert_return (invoke "f64.epsilon") (f64.const 0x1p-52)) + +;; Test that floating-point numbers are not optimized as if they form a +;; trichotomy. + +(module + (func $f32.no_trichotomy_lt (param $x f32) (param $y f32) (result i32) + (i32.or (f32.lt (get_local $x) (get_local $y)) (f32.ge (get_local $x) (get_local $y)))) + (export "f32.no_trichotomy_lt" $f32.no_trichotomy_lt) + (func $f32.no_trichotomy_le (param $x f32) (param $y f32) (result i32) + (i32.or (f32.le (get_local $x) (get_local $y)) (f32.gt (get_local $x) (get_local $y)))) + (export "f32.no_trichotomy_le" $f32.no_trichotomy_le) + (func $f32.no_trichotomy_gt (param $x f32) (param $y f32) (result i32) + (i32.or (f32.gt (get_local $x) (get_local $y)) (f32.le (get_local $x) (get_local $y)))) + (export "f32.no_trichotomy_gt" $f32.no_trichotomy_gt) + (func $f32.no_trichotomy_ge (param $x f32) (param $y f32) (result i32) + (i32.or (f32.ge (get_local $x) (get_local $y)) (f32.lt (get_local $x) (get_local $y)))) + (export "f32.no_trichotomy_ge" $f32.no_trichotomy_ge) + + (func $f64.no_trichotomy_lt (param $x f64) (param $y f64) (result i32) + (i32.or (f64.lt (get_local $x) (get_local $y)) (f64.ge (get_local $x) (get_local $y)))) + (export "f64.no_trichotomy_lt" $f64.no_trichotomy_lt) + (func $f64.no_trichotomy_le (param $x f64) (param $y f64) (result i32) + (i32.or (f64.le (get_local $x) (get_local $y)) (f64.gt (get_local $x) (get_local $y)))) + (export "f64.no_trichotomy_le" $f64.no_trichotomy_le) + (func $f64.no_trichotomy_gt (param $x f64) (param $y f64) (result i32) + (i32.or (f64.gt (get_local $x) (get_local $y)) (f64.le (get_local $x) (get_local $y)))) + (export "f64.no_trichotomy_gt" $f64.no_trichotomy_gt) + (func $f64.no_trichotomy_ge (param $x f64) (param $y f64) (result i32) + (i32.or (f64.ge (get_local $x) (get_local $y)) (f64.lt (get_local $x) (get_local $y)))) + (export "f64.no_trichotomy_ge" $f64.no_trichotomy_ge) +) + +(assert_return (invoke "f32.no_trichotomy_lt" (f32.const 0.0) (f32.const nan)) (i32.const 0)) +(assert_return (invoke "f32.no_trichotomy_le" (f32.const 0.0) (f32.const nan)) (i32.const 0)) +(assert_return (invoke "f32.no_trichotomy_gt" (f32.const 0.0) (f32.const nan)) (i32.const 0)) +(assert_return (invoke "f32.no_trichotomy_ge" (f32.const 0.0) (f32.const nan)) (i32.const 0)) +(assert_return (invoke "f64.no_trichotomy_lt" (f64.const 0.0) (f64.const nan)) (i32.const 0)) +(assert_return (invoke "f64.no_trichotomy_le" (f64.const 0.0) (f64.const nan)) (i32.const 0)) +(assert_return (invoke "f64.no_trichotomy_gt" (f64.const 0.0) (f64.const nan)) (i32.const 0)) +(assert_return (invoke "f64.no_trichotomy_ge" (f64.const 0.0) (f64.const nan)) (i32.const 0)) From 43e778de6dc38ccae03ea6eeba81cdfaeeec98b5 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 15 Jul 2016 12:50:34 -0700 Subject: [PATCH 10/13] Simplify the 7x test to be a 6x test, which also demonstrates the unsafe optimization. --- ml-proto/test/float_exprs.wast | 38 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/ml-proto/test/float_exprs.wast b/ml-proto/test/float_exprs.wast index 5c4a6e1b69..f794fa582f 100644 --- a/ml-proto/test/float_exprs.wast +++ b/ml-proto/test/float_exprs.wast @@ -1569,35 +1569,35 @@ (assert_return_nan (invoke "f64.no_fold_add_neg" (f64.const infinity))) (assert_return_nan (invoke "f64.no_fold_add_neg" (f64.const -infinity))) -;; Test that x+x+x+x+x+x+x is not folded to x * 7. +;; Test that x+x+x+x+x+x is not folded to x * 6. (module - (func $f32.no_fold_7x_via_add (param $x f32) (result f32) - (f32.add (f32.add (f32.add (f32.add (f32.add (f32.add + (func $f32.no_fold_6x_via_add (param $x f32) (result f32) + (f32.add (f32.add (f32.add (f32.add (f32.add (get_local $x) (get_local $x)) (get_local $x)) (get_local $x)) - (get_local $x)) (get_local $x)) (get_local $x))) - (export "f32.no_fold_7x_via_add" $f32.no_fold_7x_via_add) + (get_local $x)) (get_local $x))) + (export "f32.no_fold_6x_via_add" $f32.no_fold_6x_via_add) - (func $f64.no_fold_7x_via_add (param $x f64) (result f64) - (f64.add (f64.add (f64.add (f64.add (f64.add (f64.add + (func $f64.no_fold_6x_via_add (param $x f64) (result f64) + (f64.add (f64.add (f64.add (f64.add (f64.add (get_local $x) (get_local $x)) (get_local $x)) (get_local $x)) - (get_local $x)) (get_local $x)) (get_local $x))) - (export "f64.no_fold_7x_via_add" $f64.no_fold_7x_via_add) + (get_local $x)) (get_local $x))) + (export "f64.no_fold_6x_via_add" $f64.no_fold_6x_via_add) ) -(assert_return (invoke "f32.no_fold_7x_via_add" (f32.const -0x1.30f15cp+21)) (f32.const -0x1.0ad332p+24)) -(assert_return (invoke "f32.no_fold_7x_via_add" (f32.const 0x1.a51c14p+11)) (f32.const 0x1.70789p+14)) -(assert_return (invoke "f32.no_fold_7x_via_add" (f32.const 0x1.f03e64p-116)) (f32.const 0x1.b23696p-113)) -(assert_return (invoke "f32.no_fold_7x_via_add" (f32.const -0x1.f15fecp-85)) (f32.const -0x1.b333fp-82)) -(assert_return (invoke "f32.no_fold_7x_via_add" (f32.const -0x1.1a38aep-71)) (f32.const -0x1.ede332p-69)) +(assert_return (invoke "f32.no_fold_6x_via_add" (f32.const -0x1.598a0cp+99)) (f32.const -0x1.03278ap+102)) +(assert_return (invoke "f32.no_fold_6x_via_add" (f32.const -0x1.d3e7acp-77)) (f32.const -0x1.5eedc2p-74)) +(assert_return (invoke "f32.no_fold_6x_via_add" (f32.const 0x1.00fa02p-77)) (f32.const 0x1.817702p-75)) +(assert_return (invoke "f32.no_fold_6x_via_add" (f32.const -0x1.51f434p-31)) (f32.const -0x1.faee4cp-29)) +(assert_return (invoke "f32.no_fold_6x_via_add" (f32.const -0x1.00328ap+80)) (f32.const -0x1.804bcep+82)) -(assert_return (invoke "f64.no_fold_7x_via_add" (f64.const -0x1.07899efbf7601p+404)) (f64.const -0x1.cd30d638f0e81p+406)) -(assert_return (invoke "f64.no_fold_7x_via_add" (f64.const -0x1.0f4ae73f5f74bp-412)) (f64.const -0x1.dac314aee70c4p-410)) -(assert_return (invoke "f64.no_fold_7x_via_add" (f64.const -0x1.1eb6bb5682abap+554)) (f64.const -0x1.f5bfc7d764ac4p+556)) -(assert_return (invoke "f64.no_fold_7x_via_add" (f64.const 0x1.5c23a99615d72p+65)) (f64.const 0x1.309f3463531c3p+68)) -(assert_return (invoke "f64.no_fold_7x_via_add" (f64.const 0x1.cc7846ee11dd4p+397)) (f64.const 0x1.92e93e104fa18p+400)) +(assert_return (invoke "f64.no_fold_6x_via_add" (f64.const -0x1.310e15acaffe6p+68)) (f64.const -0x1.c995208307fdap+70)) +(assert_return (invoke "f64.no_fold_6x_via_add" (f64.const -0x1.aad62c78fa9b4p-535)) (f64.const -0x1.4020a15abbf46p-532)) +(assert_return (invoke "f64.no_fold_6x_via_add" (f64.const -0x1.f8fbfa94f6ab2p+271)) (f64.const -0x1.7abcfbefb9005p+274)) +(assert_return (invoke "f64.no_fold_6x_via_add" (f64.const 0x1.756ccc2830a8ep+751)) (f64.const 0x1.1811991e247ebp+754)) +(assert_return (invoke "f64.no_fold_6x_via_add" (f64.const -0x1.8fd1ab1d2402ap+234)) (f64.const -0x1.2bdd4055db01fp+237)) ;; Test that (x/y)/z is not optimized to x/(y*z), ;; which is an "allowable alternative Form" in Fortran. From 37d72325297878057c5a22d6f3291f18c54d1faf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 15 Jul 2016 12:50:37 -0700 Subject: [PATCH 11/13] Test more interesting demote rounding cases. --- ml-proto/test/conversions.wast | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/ml-proto/test/conversions.wast b/ml-proto/test/conversions.wast index 91ee9d67a5..a102f9bb68 100644 --- a/ml-proto/test/conversions.wast +++ b/ml-proto/test/conversions.wast @@ -365,10 +365,20 @@ (assert_return (invoke "f32.demote_f64" (f64.const -0x0.0000000000001p-1022)) (f32.const -0.0)) (assert_return (invoke "f32.demote_f64" (f64.const 1.0)) (f32.const 1.0)) (assert_return (invoke "f32.demote_f64" (f64.const -1.0)) (f32.const -1.0)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x1p-149)) (f32.const -0x1p-149)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffe0000000p-127)) (f32.const 0x1p-126)) +(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffe0000000p-127)) (f32.const -0x1p-126)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffdfffffffp-127)) (f32.const 0x1.fffffcp-127)) +(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffdfffffffp-127)) (f32.const -0x1.fffffcp-127)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1p-149)) (f32.const 0x1p-149)) +(assert_return (invoke "f32.demote_f64" (f64.const -0x1p-149)) (f32.const -0x1p-149)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffd0000000p+127)) (f32.const 0x1.fffffcp+127)) +(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffd0000000p+127)) (f32.const -0x1.fffffcp+127)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffd0000001p+127)) (f32.const 0x1.fffffep+127)) +(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffd0000001p+127)) (f32.const -0x1.fffffep+127)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) (assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffep+127)) (f32.const -0x1.fffffep+127)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffefffffffp+127)) (f32.const 0x1.fffffep+127)) +(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffefffffffp+127)) (f32.const -0x1.fffffep+127)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.ffffffp+127)) (f32.const infinity)) (assert_return (invoke "f32.demote_f64" (f64.const -0x1.ffffffp+127)) (f32.const -infinity)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1p-119)) (f32.const 0x1p-119)) @@ -377,8 +387,15 @@ (assert_return (invoke "f32.demote_f64" (f64.const -infinity)) (f32.const -infinity)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000000000001p+0)) (f32.const 1.0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffffffffffp-1)) (f32.const 1.0)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000000p+0)) (f32.const 0x1.000000p+0)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000001p+0)) (f32.const 0x1.000002p+0)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.000002fffffffp+0)) (f32.const 0x1.000002p+0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000030000000p+0)) (f32.const 0x1.000004p+0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000050000000p+0)) (f32.const 0x1.000004p+0)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000000p+24)) (f32.const 0x1.0p+24)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000001p+24)) (f32.const 0x1.000002p+24)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.000002fffffffp+24)) (f32.const 0x1.000002p+24)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000030000000p+24)) (f32.const 0x1.000004p+24)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.4eae4f7024c7p+108)) (f32.const 0x1.4eae5p+108)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.a12e71e358685p-113)) (f32.const 0x1.a12e72p-113)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.cb98354d521ffp-127)) (f32.const 0x1.cb9834p-127)) @@ -387,8 +404,8 @@ (assert_return (invoke "f32.demote_f64" (f64.const nan)) (f32.const nan)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1p-1022)) (f32.const 0.0)) (assert_return (invoke "f32.demote_f64" (f64.const -0x1p-1022)) (f32.const -0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const 0x0.8p-149)) (f32.const 0.0)) -(assert_return (invoke "f32.demote_f64" (f64.const -0x0.8p-149)) (f32.const -0.0)) +(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0p-150)) (f32.const 0.0)) +(assert_return (invoke "f32.demote_f64" (f64.const -0x1.0p-150)) (f32.const -0.0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000000000001p-150)) (f32.const 0x1p-149)) (assert_return (invoke "f32.demote_f64" (f64.const -0x1.0000000000001p-150)) (f32.const -0x1p-149)) From a877a64e45dd2b25b4435fcae80372be50db80da Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 15 Jul 2016 12:50:40 -0700 Subject: [PATCH 12/13] Tidy up a few TestingTodo.md items. --- ml-proto/TestingTodo.md | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/ml-proto/TestingTodo.md b/ml-proto/TestingTodo.md index f725f2a5d7..be324057f5 100644 --- a/ml-proto/TestingTodo.md +++ b/ml-proto/TestingTodo.md @@ -4,16 +4,6 @@ specified in have a link to an open issue/PR, or be obvious. Comments/corrections/additions welcome. -Misc semantics: - - ~~test that linear memory is little-endian for all integers and floats~~ - - test that unaligned and misaligned accesses work, even if slow - - ~~test that runaway recursion traps~~ - - test that too-big `grow_memory` fails appropriately - - test that too-big linear memory initial allocation fails - - test that function addresses are monotonic indices, and not actual addresses. - - ~~test that non-pagesize `grow_memory` fails~~ - - test that one can clobber the entire contents of the linear memory without corrupting: call stack, local variables, program execution. - Operator semantics: - ~~test that promote/demote is bit-preserving if not NaN~~ - ~~test that clz/ctz handle zero~~ @@ -54,19 +44,27 @@ Floating point semantics: Linear memory semantics: - test that loading from null works - - test that loading from constant OOB traps and is not DCE'd or folded (pending [discussion](https://github.com/WebAssembly/design/blob/master/AstSemantics.md#out-of-bounds)) + - ~~test that loading from constant OOB traps and is not DCE'd or folded (pending [discussion](https://github.com/WebAssembly/design/blob/master/AstSemantics.md#out-of-bounds))~~ - test that loading from "beyond the STACKPTR" succeeds - test that "stackptr + (linearmemptr - stackptr)" loads from linearmemptr. - test loading "uninitialized" things from aliased stack frames return what's there - test that loadwithoffset traps in overflow cases - - test that newly allocated memory is zeroed - - test that grow_memory does a full 32-bit unsigned check for page_size divisibility + - test that newly allocated memory (program start and `grow_memory`) is zeroed + - test that `grow_memory` does a full 32-bit unsigned check for page-size divisibility - test that load/store addreses are full int32 (or int64), and not OCaml int - test that when allocating 4GiB, accessing index -1 fails + - ~~test that linear memory is little-endian for all integers and floats~~ + - test that unaligned and misaligned accesses work, even if slow + - ~~test that runaway recursion traps~~ + - test that too-big `grow_memory` fails appropriately + - test that too-big linear memory initial allocation fails + - ~~test that non-pagesize `grow_memory` fails~~ + - test that one can clobber the entire contents of the linear memory without corrupting: call stack, local variables, program execution. + - test that an i64 store with 4-byte alignment that's 4 bytes out of bounds traps without storing anything. Function pointer semantics: - test that function addresses are monotonic indices, and not actual addresses. - - test that function pointers work [correctly](https://github.com/WebAssembly/design/issues/89) + - ~~test that function pointers work [correctly](https://github.com/WebAssembly/design/issues/89)~~ Expression optimizer bait: - ~~test that `a+1 Date: Fri, 15 Jul 2016 06:46:29 -0700 Subject: [PATCH 13/13] Test for invalid extending loads and wrapping/demoting stores. --- ml-proto/TestingTodo.md | 4 ++-- ml-proto/test/f32.load32.fail.wast | 1 + ml-proto/test/f32.load64.fail.wast | 1 + ml-proto/test/f32.store32.fail.wast | 1 + ml-proto/test/f32.store64.fail.wast | 1 + ml-proto/test/f64.load32.fail.wast | 1 + ml-proto/test/f64.load64.fail.wast | 1 + ml-proto/test/f64.store32.fail.wast | 1 + ml-proto/test/f64.store64.fail.wast | 1 + ml-proto/test/i32.load32_s.fail.wast | 1 + ml-proto/test/i32.load32_u.fail.wast | 1 + ml-proto/test/i32.load64_s.fail.wast | 1 + ml-proto/test/i32.load64_u.fail.wast | 1 + ml-proto/test/i32.store32.fail.wast | 1 + ml-proto/test/i32.store64.fail.wast | 1 + ml-proto/test/i64.load64_s.fail.wast | 1 + ml-proto/test/i64.load64_u.fail.wast | 1 + ml-proto/test/i64.store64.fail.wast | 1 + 18 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 ml-proto/test/f32.load32.fail.wast create mode 100644 ml-proto/test/f32.load64.fail.wast create mode 100644 ml-proto/test/f32.store32.fail.wast create mode 100644 ml-proto/test/f32.store64.fail.wast create mode 100644 ml-proto/test/f64.load32.fail.wast create mode 100644 ml-proto/test/f64.load64.fail.wast create mode 100644 ml-proto/test/f64.store32.fail.wast create mode 100644 ml-proto/test/f64.store64.fail.wast create mode 100644 ml-proto/test/i32.load32_s.fail.wast create mode 100644 ml-proto/test/i32.load32_u.fail.wast create mode 100644 ml-proto/test/i32.load64_s.fail.wast create mode 100644 ml-proto/test/i32.load64_u.fail.wast create mode 100644 ml-proto/test/i32.store32.fail.wast create mode 100644 ml-proto/test/i32.store64.fail.wast create mode 100644 ml-proto/test/i64.load64_s.fail.wast create mode 100644 ml-proto/test/i64.load64_u.fail.wast create mode 100644 ml-proto/test/i64.store64.fail.wast diff --git a/ml-proto/TestingTodo.md b/ml-proto/TestingTodo.md index be324057f5..c06248b963 100644 --- a/ml-proto/TestingTodo.md +++ b/ml-proto/TestingTodo.md @@ -109,8 +109,8 @@ Misc x87-isms: - ~~test for loading and storing NaNs~~ Validation errors: - - sign-extend load from int64 to int32 etc. - - fp-promote load and fp-demote store + - ~~sign-extend load from int64 to int32 etc.~~ + - ~~fp-promote load and fp-demote store~~ - alignment greater than the size of a load or store (https://github.com/WebAssembly/spec/issues/302) SIMD (post-MVP): diff --git a/ml-proto/test/f32.load32.fail.wast b/ml-proto/test/f32.load32.fail.wast new file mode 100644 index 0000000000..313364538c --- /dev/null +++ b/ml-proto/test/f32.load32.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (result f32) (f32.load32 (get_local 0)))) diff --git a/ml-proto/test/f32.load64.fail.wast b/ml-proto/test/f32.load64.fail.wast new file mode 100644 index 0000000000..da94668fc2 --- /dev/null +++ b/ml-proto/test/f32.load64.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (result f32) (f32.load64 (get_local 0)))) diff --git a/ml-proto/test/f32.store32.fail.wast b/ml-proto/test/f32.store32.fail.wast new file mode 100644 index 0000000000..3daf6eb35e --- /dev/null +++ b/ml-proto/test/f32.store32.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (param f32) (f32.store32 (get_local 0) (get_local 1)))) diff --git a/ml-proto/test/f32.store64.fail.wast b/ml-proto/test/f32.store64.fail.wast new file mode 100644 index 0000000000..b2c47bb9b4 --- /dev/null +++ b/ml-proto/test/f32.store64.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (param f64) (f32.store64 (get_local 0) (get_local 1)))) diff --git a/ml-proto/test/f64.load32.fail.wast b/ml-proto/test/f64.load32.fail.wast new file mode 100644 index 0000000000..38811ff353 --- /dev/null +++ b/ml-proto/test/f64.load32.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (result f64) (f64.load32 (get_local 0)))) diff --git a/ml-proto/test/f64.load64.fail.wast b/ml-proto/test/f64.load64.fail.wast new file mode 100644 index 0000000000..f3c30ef345 --- /dev/null +++ b/ml-proto/test/f64.load64.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (result f64) (f64.load64 (get_local 0)))) diff --git a/ml-proto/test/f64.store32.fail.wast b/ml-proto/test/f64.store32.fail.wast new file mode 100644 index 0000000000..92858a35e0 --- /dev/null +++ b/ml-proto/test/f64.store32.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (param f32) (f64.store32 (get_local 0) (get_local 1)))) diff --git a/ml-proto/test/f64.store64.fail.wast b/ml-proto/test/f64.store64.fail.wast new file mode 100644 index 0000000000..2b49017fe1 --- /dev/null +++ b/ml-proto/test/f64.store64.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (param f64) (f64.store64 (get_local 0) (get_local 1)))) diff --git a/ml-proto/test/i32.load32_s.fail.wast b/ml-proto/test/i32.load32_s.fail.wast new file mode 100644 index 0000000000..abf38966ad --- /dev/null +++ b/ml-proto/test/i32.load32_s.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (result i32) (i32.load32_s (get_local 0)))) diff --git a/ml-proto/test/i32.load32_u.fail.wast b/ml-proto/test/i32.load32_u.fail.wast new file mode 100644 index 0000000000..26df00312b --- /dev/null +++ b/ml-proto/test/i32.load32_u.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (result i32) (i32.load32_u (get_local 0)))) diff --git a/ml-proto/test/i32.load64_s.fail.wast b/ml-proto/test/i32.load64_s.fail.wast new file mode 100644 index 0000000000..78fa012796 --- /dev/null +++ b/ml-proto/test/i32.load64_s.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (result i32) (i32.load64_s (get_local 0)))) diff --git a/ml-proto/test/i32.load64_u.fail.wast b/ml-proto/test/i32.load64_u.fail.wast new file mode 100644 index 0000000000..01e8273e6a --- /dev/null +++ b/ml-proto/test/i32.load64_u.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (result i32) (i32.load64_u (get_local 0)))) diff --git a/ml-proto/test/i32.store32.fail.wast b/ml-proto/test/i32.store32.fail.wast new file mode 100644 index 0000000000..8a6c528d66 --- /dev/null +++ b/ml-proto/test/i32.store32.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (param i32) (i32.store32 (get_local 0) (get_local 1)))) diff --git a/ml-proto/test/i32.store64.fail.wast b/ml-proto/test/i32.store64.fail.wast new file mode 100644 index 0000000000..cb176d23e2 --- /dev/null +++ b/ml-proto/test/i32.store64.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (param i64) (i32.store64 (get_local 0) (get_local 1)))) diff --git a/ml-proto/test/i64.load64_s.fail.wast b/ml-proto/test/i64.load64_s.fail.wast new file mode 100644 index 0000000000..335bac35ab --- /dev/null +++ b/ml-proto/test/i64.load64_s.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (result i64) (i64.load64_s (get_local 0)))) diff --git a/ml-proto/test/i64.load64_u.fail.wast b/ml-proto/test/i64.load64_u.fail.wast new file mode 100644 index 0000000000..b9002e2bf6 --- /dev/null +++ b/ml-proto/test/i64.load64_u.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (result i64) (i64.load64_u (get_local 0)))) diff --git a/ml-proto/test/i64.store64.fail.wast b/ml-proto/test/i64.store64.fail.wast new file mode 100644 index 0000000000..918761f683 --- /dev/null +++ b/ml-proto/test/i64.store64.fail.wast @@ -0,0 +1 @@ +(module (memory 1) (func (param i32) (param i64) (i64.store64 (get_local 0) (get_local 1))))