summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/support/safe_integer.cpp4
-rw-r--r--test/spec/conversions.wast19
2 files changed, 18 insertions, 5 deletions
diff --git a/src/support/safe_integer.cpp b/src/support/safe_integer.cpp
index 4afc7afea..d99508b17 100644
--- a/src/support/safe_integer.cpp
+++ b/src/support/safe_integer.cpp
@@ -125,7 +125,7 @@ bool wasm::isInRangeI64TruncU(int32_t i) {
* ---------------------------------
* 0 00000000000 0000...000000...000 0x0000000000000000 => 0
* 0 10000011101 1111...111000...111 0x41dfffffffffffff => 2147483647.9999998 (rounds down to INT32_MAX)
- * 0 10000011110 1111...111100...000 0x41efffffffe00000 => 4294967295 (UINT32_MAX)
+ * 0 10000011110 1111...111111...111 0x41efffffffffffff => 4294967295.9999995 (rounds down to UINT32_MAX)
* 0 10000111101 1111...111111...111 0x43dfffffffffffff => 9223372036854774784 (~INT64_MAX)
* 0 10000111110 0000...000000...000 0x43e0000000000000 => 9223372036854775808
* 0 10000111110 1111...111111...111 0x43efffffffffffff => 18446744073709549568 (~UINT64_MAX)
@@ -152,7 +152,7 @@ bool wasm::isInRangeI32TruncS(int64_t i) {
bool wasm::isInRangeI32TruncU(int64_t i) {
uint64_t u = i;
- return (u <= 0x41efffffffe00000ULL) ||
+ return (u <= 0x41efffffffffffffULL) ||
(u >= 0x8000000000000000ULL && u <= 0xbfefffffffffffffULL);
}
diff --git a/test/spec/conversions.wast b/test/spec/conversions.wast
index 4e779aa8e..439d5cfd6 100644
--- a/test/spec/conversions.wast
+++ b/test/spec/conversions.wast
@@ -112,9 +112,6 @@
(assert_return (invoke "i32.trunc_f64_s" (f64.const -2.0)) (i32.const -2))
(assert_return (invoke "i32.trunc_f64_s" (f64.const 2147483647.0)) (i32.const 2147483647))
(assert_return (invoke "i32.trunc_f64_s" (f64.const -2147483648.0)) (i32.const -2147483648))
-(assert_return (invoke "i32.trunc_f64_s" (f64.const -2147483648.9999995)) (i32.const -2147483648))
-(assert_return (invoke "i32.trunc_f64_s" (f64.const 2147483647.9999998)) (i32.const 2147483647))
-(assert_trap (invoke "i32.trunc_f64_s" (f64.const 2147483647.9999999)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_s" (f64.const 2147483648.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_s" (f64.const -2147483649.0)) "integer overflow")
(assert_trap (invoke "i32.trunc_f64_s" (f64.const inf)) "integer overflow")
@@ -124,6 +121,22 @@
(assert_trap (invoke "i32.trunc_f64_s" (f64.const -nan)) "invalid conversion to integer")
(assert_trap (invoke "i32.trunc_f64_s" (f64.const -nan:0x4000000000000)) "invalid conversion to integer")
+;; f64 -> i32 rounding to the exact i32 limit
+(assert_return (invoke "i32.trunc_f64_s" (f64.const -2147483648.9)) (i32.const -2147483648))
+(assert_return (invoke "i32.trunc_f64_s" (f64.const 2147483647.9)) (i32.const 2147483647))
+(assert_return (invoke "i32.trunc_f64_u" (f64.const -0.9)) (i32.const 0))
+(assert_return (invoke "i32.trunc_f64_u" (f64.const 4294967295.9)) (i32.const 4294967295))
+
+;; f64 -> i32 rounding at the exact boundary + float parsing
+(assert_return (invoke "i32.trunc_f64_s" (f64.const -2147483648.9999997)) (i32.const -2147483648))
+(assert_trap (invoke "i32.trunc_f64_s" (f64.const -2147483648.9999998)) "integer overflow")
+(assert_return (invoke "i32.trunc_f64_s" (f64.const 2147483647.9999998)) (i32.const 2147483647))
+(assert_trap (invoke "i32.trunc_f64_s" (f64.const 2147483647.9999999)) "integer overflow")
+(assert_return (invoke "i32.trunc_f64_u" (f64.const -0.99999999999999994)) (i32.const 0))
+(assert_trap (invoke "i32.trunc_f64_u" (f64.const -0.99999999999999995)) "integer overflow")
+(assert_return (invoke "i32.trunc_f64_u" (f64.const 4294967295.9999997)) (i32.const 4294967295))
+(assert_trap (invoke "i32.trunc_f64_u" (f64.const 4294967295.9999998)) "integer overflow")
+
(assert_return (invoke "i32.trunc_f64_u" (f64.const 0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_u" (f64.const -0.0)) (i32.const 0))
(assert_return (invoke "i32.trunc_f64_u" (f64.const 0x0.0000000000001p-1022)) (i32.const 0))