Commit f44e5870 authored by Alberto Donizetti's avatar Alberto Donizetti Committed by Russ Cox

math: check overflow in amd64 Exp implementation

Unlike the pure go implementation used by every other architecture,
the amd64 asm implementation of Exp does not fail early if the
argument is known to overflow. Make it fail early.

Cost of the check is < 1ns (on an old Sandy Bridge machine):

name   old time/op  new time/op  delta
Exp-4  18.3ns ± 1%  18.7ns ± 1%  +2.08%  (p=0.000 n=18+20)

Fixes #14932
Fixes #18912

Change-Id: I04b3f9b4ee853822cbdc97feade726fbe2907289
Reviewed-on: https://go-review.googlesource.com/36271
Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com>
Reviewed-by: default avatarRuss Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 4fafc843
......@@ -947,6 +947,11 @@ var vfexpSC = []float64{
2000,
Inf(1),
NaN(),
// smallest float64 that overflows Exp(x)
7.097827128933841e+02,
// Issue 18912
1.48852223e+09,
1.4885222e+09,
}
var expSC = []float64{
0,
......@@ -954,6 +959,27 @@ var expSC = []float64{
Inf(1),
Inf(1),
NaN(),
Inf(1),
Inf(1),
Inf(1),
}
var vfexp2SC = []float64{
Inf(-1),
-2000,
2000,
Inf(1),
NaN(),
// smallest float64 that overflows Exp2(x)
1024,
}
var exp2SC = []float64{
0,
0,
Inf(1),
Inf(1),
NaN(),
Inf(1),
}
var vfexpm1SC = []float64{
......@@ -2089,8 +2115,8 @@ func testExp2(t *testing.T, Exp2 func(float64) float64, name string) {
t.Errorf("%s(%g) = %g, want %g", name, vf[i], f, exp2[i])
}
}
for i := 0; i < len(vfexpSC); i++ {
if f := Exp2(vfexpSC[i]); !alike(expSC[i], f) {
for i := 0; i < len(vfexp2SC); i++ {
if f := Exp2(vfexp2SC[i]); !alike(exp2SC[i], f) {
t.Errorf("%s(%g) = %g, want %g", name, vfexpSC[i], f, expSC[i])
}
}
......
......@@ -31,10 +31,11 @@
#define T7 2.4801587301587301587e-5
#define PosInf 0x7FF0000000000000
#define NegInf 0xFFF0000000000000
#define Overflow 7.09782712893384e+02
// func Exp(x float64) float64
TEXT ·Exp(SB),NOSPLIT,$0
// test bits for not-finite
// test bits for not-finite
MOVQ x+0(FP), BX
MOVQ $~(1<<63), AX // sign bit mask
MOVQ BX, DX
......@@ -42,7 +43,11 @@ TEXT ·Exp(SB),NOSPLIT,$0
MOVQ $PosInf, AX
CMPQ AX, DX
JLE notFinite
// check if argument will overflow
MOVQ BX, X0
MOVSD $Overflow, X1
COMISD X1, X0
JA overflow
MOVSD $LOG2E, X1
MULSD X0, X1
CVTSD2SL X1, BX // BX = exponent
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment