aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAgniva De Sarker <agnivade@yahoo.co.in>2020-05-04 12:21:18 +0530
committerAgniva De Sarker <agniva.quicksilver@gmail.com>2020-05-06 13:55:00 +0000
commit4daf8719e7f4c71a620f650d73caab2a9d7ea499 (patch)
treeabcfd92941eae651799b1632a9679b3a4603ffe9 /src
parent0f47c12a29e6277c8139e8d4f5a45272e437fe6e (diff)
downloadgo-4daf8719e7f4c71a620f650d73caab2a9d7ea499.tar.xz
runtime: use correct truncated constants for float conversion
There is a range of numbers lower than 0x7fff_ffff_ffff_ffff which cannot be represented by a 64 bit float. We set that to the correct limit beyond which conversions can happen properly. It appears that the negative bound check can indeed by correctly handled by I64TruncF64S. But we use the same limit for consistency. Fixes #38839 Change-Id: Ib783a22cb331fba7e6955459f41c67f9ceb53461 Reviewed-on: https://go-review.googlesource.com/c/go/+/231837 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/runtime/conv_wasm_test.go128
-rw-r--r--src/runtime/sys_wasm.s6
2 files changed, 131 insertions, 3 deletions
diff --git a/src/runtime/conv_wasm_test.go b/src/runtime/conv_wasm_test.go
new file mode 100644
index 0000000000..5054fca04d
--- /dev/null
+++ b/src/runtime/conv_wasm_test.go
@@ -0,0 +1,128 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+ "testing"
+)
+
+var res int64
+var ures uint64
+
+func TestFloatTruncation(t *testing.T) {
+ testdata := []struct {
+ input float64
+ convInt64 int64
+ convUInt64 uint64
+ overflow bool
+ }{
+ // max +- 1
+ {
+ input: 0x7fffffffffffffff,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ // For out-of-bounds conversion, the result is implementation-dependent.
+ // This test verifies the implementation of wasm architecture.
+ {
+ input: 0x8000000000000000,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ {
+ input: 0x7ffffffffffffffe,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ // neg max +- 1
+ {
+ input: -0x8000000000000000,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ {
+ input: -0x8000000000000001,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ {
+ input: -0x7fffffffffffffff,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ // trunc point +- 1
+ {
+ input: 0x7ffffffffffffdff,
+ convInt64: 0x7ffffffffffffc00,
+ convUInt64: 0x7ffffffffffffc00,
+ },
+ {
+ input: 0x7ffffffffffffe00,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ {
+ input: 0x7ffffffffffffdfe,
+ convInt64: 0x7ffffffffffffc00,
+ convUInt64: 0x7ffffffffffffc00,
+ },
+ // neg trunc point +- 1
+ {
+ input: -0x7ffffffffffffdff,
+ convInt64: -0x7ffffffffffffc00,
+ convUInt64: 0x8000000000000000,
+ },
+ {
+ input: -0x7ffffffffffffe00,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ {
+ input: -0x7ffffffffffffdfe,
+ convInt64: -0x7ffffffffffffc00,
+ convUInt64: 0x8000000000000000,
+ },
+ // umax +- 1
+ {
+ input: 0xffffffffffffffff,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ {
+ input: 0x10000000000000000,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ {
+ input: 0xfffffffffffffffe,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ // umax trunc +- 1
+ {
+ input: 0xfffffffffffffbff,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0xfffffffffffff800,
+ },
+ {
+ input: 0xfffffffffffffc00,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0x8000000000000000,
+ },
+ {
+ input: 0xfffffffffffffbfe,
+ convInt64: -0x8000000000000000,
+ convUInt64: 0xfffffffffffff800,
+ },
+ }
+ for _, item := range testdata {
+ if got, want := int64(item.input), item.convInt64; got != want {
+ t.Errorf("int64(%f): got %x, want %x", item.input, got, want)
+ }
+ if got, want := uint64(item.input), item.convUInt64; got != want {
+ t.Errorf("uint64(%f): got %x, want %x", item.input, got, want)
+ }
+ }
+}
diff --git a/src/runtime/sys_wasm.s b/src/runtime/sys_wasm.s
index 41260bdf23..e7a6570095 100644
--- a/src/runtime/sys_wasm.s
+++ b/src/runtime/sys_wasm.s
@@ -99,7 +99,7 @@ TEXT runtime·wasmTruncS(SB), NOSPLIT, $0-0
End
Get R0
- F64Const $9223372036854775807.
+ F64Const $0x7ffffffffffffc00p0 // Maximum truncated representation of 0x7fffffffffffffff
F64Gt
If
I64Const $0x8000000000000000
@@ -107,7 +107,7 @@ TEXT runtime·wasmTruncS(SB), NOSPLIT, $0-0
End
Get R0
- F64Const $-9223372036854775808.
+ F64Const $-0x7ffffffffffffc00p0 // Minimum truncated representation of -0x8000000000000000
F64Lt
If
I64Const $0x8000000000000000
@@ -128,7 +128,7 @@ TEXT runtime·wasmTruncU(SB), NOSPLIT, $0-0
End
Get R0
- F64Const $18446744073709551615.
+ F64Const $0xfffffffffffff800p0 // Maximum truncated representation of 0xffffffffffffffff
F64Gt
If
I64Const $0x8000000000000000