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>
This commit is contained in:
Agniva De Sarker 2020-05-04 12:21:18 +05:30 committed by Agniva De Sarker
parent 0f47c12a29
commit 4daf8719e7
2 changed files with 131 additions and 3 deletions

View File

@ -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)
}
}
}

View 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