]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use correct truncated constants for float conversion
authorAgniva De Sarker <agnivade@yahoo.co.in>
Mon, 4 May 2020 06:51:18 +0000 (12:21 +0530)
committerAgniva De Sarker <agniva.quicksilver@gmail.com>
Wed, 6 May 2020 13:55:00 +0000 (13:55 +0000)
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>

src/runtime/conv_wasm_test.go [new file with mode: 0644]
src/runtime/sys_wasm.s

diff --git a/src/runtime/conv_wasm_test.go b/src/runtime/conv_wasm_test.go
new file mode 100644 (file)
index 0000000..5054fca
--- /dev/null
@@ -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)
+               }
+       }
+}
index 41260bdf23e28ebc292f43ba9df99a7b1842b81a..e7a657009538c987c7441d2f13f724952ce79804 100644 (file)
@@ -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