mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: implement float min/max in hardware for riscv64
CL 514596 adds float min/max for amd64, this CL adds it for riscv64.
The behavior of the RISC-V FMIN/FMAX instructions almost match Go's
requirements.
However according to RISCV spec 8.3 "NaN Generation and Propagation"
>> if at least one input is a signaling NaN, or if both inputs are quiet
>> NaNs, the result is the canonical NaN. If one operand is a quiet NaN
>> and the other is not a NaN, the result is the non-NaN operand.
Go using quiet NaN as NaN and according to Go spec
>> if any argument is a NaN, the result is a NaN
This requires the float min/max implementation to check whether one
of operand is qNaN before float mix/max actually execute.
This CL also fix a typo in minmax test.
Benchmark on Visionfive2
goos: linux
goarch: riscv64
pkg: runtime
│ float_minmax.old.bench │ float_minmax.new.bench │
│ sec/op │ sec/op vs base │
MinFloat 158.20n ± 0% 28.13n ± 0% -82.22% (p=0.000 n=10)
MaxFloat 158.10n ± 0% 28.12n ± 0% -82.21% (p=0.000 n=10)
geomean 158.1n 28.12n -82.22%
Update #59488
Change-Id: Iab48be6d32b8882044fb8c821438ca8840e5493d
Reviewed-on: https://go-review.googlesource.com/c/go/+/514775
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
Run-TryBot: M Zhuo <mengzhuo1203@gmail.com>
Reviewed-by: Joel Sing <joel@sing.id.au>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
bdb0a1abfc
commit
09ed9a6585
7 changed files with 174 additions and 3 deletions
|
|
@ -429,6 +429,8 @@ func init() {
|
|||
{name: "FNES", argLength: 2, reg: fp2gp, asm: "FNES", commutative: true}, // arg0 != arg1
|
||||
{name: "FLTS", argLength: 2, reg: fp2gp, asm: "FLTS"}, // arg0 < arg1
|
||||
{name: "FLES", argLength: 2, reg: fp2gp, asm: "FLES"}, // arg0 <= arg1
|
||||
{name: "LoweredFMAXS", argLength: 2, reg: fp21, resultNotInArgs: true, asm: "FMAXS", commutative: true, typ: "Float32"}, // max(arg0, arg1)
|
||||
{name: "LoweredFMINS", argLength: 2, reg: fp21, resultNotInArgs: true, asm: "FMINS", commutative: true, typ: "Float32"}, // min(arg0, arg1)
|
||||
|
||||
// D extension.
|
||||
{name: "FADDD", argLength: 2, reg: fp21, asm: "FADDD", commutative: true, typ: "Float64"}, // arg0 + arg1
|
||||
|
|
@ -456,6 +458,8 @@ func init() {
|
|||
{name: "FNED", argLength: 2, reg: fp2gp, asm: "FNED", commutative: true}, // arg0 != arg1
|
||||
{name: "FLTD", argLength: 2, reg: fp2gp, asm: "FLTD"}, // arg0 < arg1
|
||||
{name: "FLED", argLength: 2, reg: fp2gp, asm: "FLED"}, // arg0 <= arg1
|
||||
{name: "LoweredFMIND", argLength: 2, reg: fp21, resultNotInArgs: true, asm: "FMIND", commutative: true, typ: "Float64"}, // min(arg0, arg1)
|
||||
{name: "LoweredFMAXD", argLength: 2, reg: fp21, resultNotInArgs: true, asm: "FMAXD", commutative: true, typ: "Float64"}, // max(arg0, arg1)
|
||||
}
|
||||
|
||||
RISCV64blocks := []blockData{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue