Skip to content

Commit

Permalink
runtime: use correct truncated constants for float conversion
Browse files Browse the repository at this point in the history
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 <[email protected]>
Run-TryBot: Keith Randall <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
  • Loading branch information
agnivade committed May 6, 2020
1 parent 0f47c12 commit 4daf871
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 3 deletions.
128 changes: 128 additions & 0 deletions src/runtime/conv_wasm_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
6 changes: 3 additions & 3 deletions src/runtime/sys_wasm.s
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,15 @@ TEXT runtime·wasmTruncS(SB), NOSPLIT, $0-0
End

Get R0
F64Const $9223372036854775807.
F64Const $0x7ffffffffffffc00p0 // Maximum truncated representation of 0x7fffffffffffffff
F64Gt
If
I64Const $0x8000000000000000
Return
End

Get R0
F64Const $-9223372036854775808.
F64Const $-0x7ffffffffffffc00p0 // Minimum truncated representation of -0x8000000000000000
F64Lt
If
I64Const $0x8000000000000000
Expand All @@ -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
Expand Down

0 comments on commit 4daf871

Please sign in to comment.