mirror of
https://github.com/golang/go
synced 2024-11-26 23:11:24 -07:00
math, cmd/compile: rename Fma to FMA
This API was added for #25819, where it was discussed as math.FMA. The commit adding it used math.Fma, presumably for consistency with the rest of the unusual names in package math (Sincos, Acosh, Erfcinv, Float32bits, etc). I believe that using an idiomatic Go name is more important here than consistency with these other names, most of which are historical baggage from C's standard library. Early additions like Float32frombits happened before "uppercase for export" (so they were originally like "float32frombits") and they were not properly reconsidered when we uppercased the symbols to export them. That's a mistake we live with. The names of functions we have added since then, and even a few that were legacy, are more properly Go-cased, such as IsNaN, IsInf, and RoundToEven, rather than Isnan, Isinf, and Roundtoeven. And also constants like MaxFloat32. For new API, we should keep using proper Go-cased symbols instead of minimally-upper-cased-C symbols. So math.FMA, not math.Fma. This API has not yet been released, so this change does not break the compatibility promise. This CL also modifies cmd/compile, since the compiler knows the name of the function. I could have stopped at changing the string constants, but it seemed to make more sense to use a consistent casing everywhere. Change-Id: I0f6f3407f41e99bfa8239467345c33945088896e Reviewed-on: https://go-review.googlesource.com/c/go/+/205317 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
3b1ae308a4
commit
543c6d2e0d
@ -3561,12 +3561,12 @@ func init() {
|
|||||||
return s.newValue2(ssa.OpCopysign, types.Types[TFLOAT64], args[0], args[1])
|
return s.newValue2(ssa.OpCopysign, types.Types[TFLOAT64], args[0], args[1])
|
||||||
},
|
},
|
||||||
sys.PPC64, sys.Wasm)
|
sys.PPC64, sys.Wasm)
|
||||||
addF("math", "Fma",
|
addF("math", "FMA",
|
||||||
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
||||||
return s.newValue3(ssa.OpFma, types.Types[TFLOAT64], args[0], args[1], args[2])
|
return s.newValue3(ssa.OpFMA, types.Types[TFLOAT64], args[0], args[1], args[2])
|
||||||
},
|
},
|
||||||
sys.ARM64, sys.PPC64, sys.S390X)
|
sys.ARM64, sys.PPC64, sys.S390X)
|
||||||
addF("math", "Fma",
|
addF("math", "FMA",
|
||||||
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
||||||
if !s.config.UseFMA {
|
if !s.config.UseFMA {
|
||||||
a := s.call(n, callNormal)
|
a := s.call(n, callNormal)
|
||||||
@ -3587,7 +3587,7 @@ func init() {
|
|||||||
|
|
||||||
// We have the intrinsic - use it directly.
|
// We have the intrinsic - use it directly.
|
||||||
s.startBlock(bTrue)
|
s.startBlock(bTrue)
|
||||||
s.vars[n] = s.newValue3(ssa.OpFma, types.Types[TFLOAT64], args[0], args[1], args[2])
|
s.vars[n] = s.newValue3(ssa.OpFMA, types.Types[TFLOAT64], args[0], args[1], args[2])
|
||||||
s.endBlock().AddEdgeTo(bEnd)
|
s.endBlock().AddEdgeTo(bEnd)
|
||||||
|
|
||||||
// Call the pure Go version.
|
// Call the pure Go version.
|
||||||
@ -3601,7 +3601,7 @@ func init() {
|
|||||||
return s.variable(n, types.Types[TFLOAT64])
|
return s.variable(n, types.Types[TFLOAT64])
|
||||||
},
|
},
|
||||||
sys.AMD64)
|
sys.AMD64)
|
||||||
addF("math", "Fma",
|
addF("math", "FMA",
|
||||||
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
|
||||||
if !s.config.UseFMA {
|
if !s.config.UseFMA {
|
||||||
a := s.call(n, callNormal)
|
a := s.call(n, callNormal)
|
||||||
@ -3622,7 +3622,7 @@ func init() {
|
|||||||
|
|
||||||
// We have the intrinsic - use it directly.
|
// We have the intrinsic - use it directly.
|
||||||
s.startBlock(bTrue)
|
s.startBlock(bTrue)
|
||||||
s.vars[n] = s.newValue3(ssa.OpFma, types.Types[TFLOAT64], args[0], args[1], args[2])
|
s.vars[n] = s.newValue3(ssa.OpFMA, types.Types[TFLOAT64], args[0], args[1], args[2])
|
||||||
s.endBlock().AddEdgeTo(bEnd)
|
s.endBlock().AddEdgeTo(bEnd)
|
||||||
|
|
||||||
// Call the pure Go version.
|
// Call the pure Go version.
|
||||||
|
@ -110,7 +110,7 @@
|
|||||||
(Floor x) -> (ROUNDSD [1] x)
|
(Floor x) -> (ROUNDSD [1] x)
|
||||||
(Ceil x) -> (ROUNDSD [2] x)
|
(Ceil x) -> (ROUNDSD [2] x)
|
||||||
(Trunc x) -> (ROUNDSD [3] x)
|
(Trunc x) -> (ROUNDSD [3] x)
|
||||||
(Fma x y z) -> (VFMADD231SD z x y)
|
(FMA x y z) -> (VFMADD231SD z x y)
|
||||||
|
|
||||||
// Lowering extension
|
// Lowering extension
|
||||||
// Note: we always extend to 64 bits even though some ops don't need that many result bits.
|
// Note: we always extend to 64 bits even though some ops don't need that many result bits.
|
||||||
|
@ -211,7 +211,7 @@
|
|||||||
(Round(32|64)F x) -> x
|
(Round(32|64)F x) -> x
|
||||||
|
|
||||||
// fused-multiply-add
|
// fused-multiply-add
|
||||||
(Fma x y z) -> (FMULAD z x y)
|
(FMA x y z) -> (FMULAD z x y)
|
||||||
|
|
||||||
// comparisons
|
// comparisons
|
||||||
(Eq8 x y) -> (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
|
(Eq8 x y) -> (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
|
||||||
|
@ -90,7 +90,7 @@
|
|||||||
(Round x) -> (FRINTAD x)
|
(Round x) -> (FRINTAD x)
|
||||||
(RoundToEven x) -> (FRINTND x)
|
(RoundToEven x) -> (FRINTND x)
|
||||||
(Trunc x) -> (FRINTZD x)
|
(Trunc x) -> (FRINTZD x)
|
||||||
(Fma x y z) -> (FMADDD z x y)
|
(FMA x y z) -> (FMADDD z x y)
|
||||||
|
|
||||||
// lowering rotates
|
// lowering rotates
|
||||||
(RotateLeft8 <t> x (MOVDconst [c])) -> (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
|
(RotateLeft8 <t> x (MOVDconst [c])) -> (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
|
||||||
|
@ -68,7 +68,7 @@
|
|||||||
(Round x) -> (FROUND x)
|
(Round x) -> (FROUND x)
|
||||||
(Copysign x y) -> (FCPSGN y x)
|
(Copysign x y) -> (FCPSGN y x)
|
||||||
(Abs x) -> (FABS x)
|
(Abs x) -> (FABS x)
|
||||||
(Fma x y z) -> (FMADD x y z)
|
(FMA x y z) -> (FMADD x y z)
|
||||||
|
|
||||||
// Lowering constants
|
// Lowering constants
|
||||||
(Const(64|32|16|8) [val]) -> (MOVDconst [val])
|
(Const(64|32|16|8) [val]) -> (MOVDconst [val])
|
||||||
|
@ -139,7 +139,7 @@
|
|||||||
(Trunc x) -> (FIDBR [5] x)
|
(Trunc x) -> (FIDBR [5] x)
|
||||||
(RoundToEven x) -> (FIDBR [4] x)
|
(RoundToEven x) -> (FIDBR [4] x)
|
||||||
(Round x) -> (FIDBR [1] x)
|
(Round x) -> (FIDBR [1] x)
|
||||||
(Fma x y z) -> (FMADD z x y)
|
(FMA x y z) -> (FMADD z x y)
|
||||||
|
|
||||||
// Atomic loads and stores.
|
// Atomic loads and stores.
|
||||||
// The SYNC instruction (fast-BCR-serialization) prevents store-load
|
// The SYNC instruction (fast-BCR-serialization) prevents store-load
|
||||||
|
@ -314,7 +314,7 @@ var genericOps = []opData{
|
|||||||
//
|
//
|
||||||
// When the multiply is an infinity times a zero, the result is NaN.
|
// When the multiply is an infinity times a zero, the result is NaN.
|
||||||
// See section 7.2 in ieee754.
|
// See section 7.2 in ieee754.
|
||||||
{name: "Fma", argLength: 3}, // compute (a*b)+c without intermediate rounding
|
{name: "FMA", argLength: 3}, // compute (a*b)+c without intermediate rounding
|
||||||
|
|
||||||
// Data movement. Max argument length for Phi is indefinite.
|
// Data movement. Max argument length for Phi is indefinite.
|
||||||
{name: "Phi", argLength: -1, zeroWidth: true}, // select an argument based on which predecessor block we came from
|
{name: "Phi", argLength: -1, zeroWidth: true}, // select an argument based on which predecessor block we came from
|
||||||
|
@ -2428,7 +2428,7 @@ const (
|
|||||||
OpRoundToEven
|
OpRoundToEven
|
||||||
OpAbs
|
OpAbs
|
||||||
OpCopysign
|
OpCopysign
|
||||||
OpFma
|
OpFMA
|
||||||
OpPhi
|
OpPhi
|
||||||
OpCopy
|
OpCopy
|
||||||
OpConvert
|
OpConvert
|
||||||
@ -30743,7 +30743,7 @@ var opcodeTable = [...]opInfo{
|
|||||||
generic: true,
|
generic: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Fma",
|
name: "FMA",
|
||||||
argLen: 3,
|
argLen: 3,
|
||||||
generic: true,
|
generic: true,
|
||||||
},
|
},
|
||||||
|
@ -770,8 +770,8 @@ func rewriteValueAMD64(v *Value) bool {
|
|||||||
return rewriteValueAMD64_OpEqPtr_0(v)
|
return rewriteValueAMD64_OpEqPtr_0(v)
|
||||||
case OpFloor:
|
case OpFloor:
|
||||||
return rewriteValueAMD64_OpFloor_0(v)
|
return rewriteValueAMD64_OpFloor_0(v)
|
||||||
case OpFma:
|
case OpFMA:
|
||||||
return rewriteValueAMD64_OpFma_0(v)
|
return rewriteValueAMD64_OpFMA_0(v)
|
||||||
case OpGeq16:
|
case OpGeq16:
|
||||||
return rewriteValueAMD64_OpGeq16_0(v)
|
return rewriteValueAMD64_OpGeq16_0(v)
|
||||||
case OpGeq16U:
|
case OpGeq16U:
|
||||||
@ -52222,8 +52222,8 @@ func rewriteValueAMD64_OpFloor_0(v *Value) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func rewriteValueAMD64_OpFma_0(v *Value) bool {
|
func rewriteValueAMD64_OpFMA_0(v *Value) bool {
|
||||||
// match: (Fma x y z)
|
// match: (FMA x y z)
|
||||||
// result: (VFMADD231SD z x y)
|
// result: (VFMADD231SD z x y)
|
||||||
for {
|
for {
|
||||||
z := v.Args[2]
|
z := v.Args[2]
|
||||||
|
@ -538,8 +538,8 @@ func rewriteValueARM(v *Value) bool {
|
|||||||
return rewriteValueARM_OpEqB_0(v)
|
return rewriteValueARM_OpEqB_0(v)
|
||||||
case OpEqPtr:
|
case OpEqPtr:
|
||||||
return rewriteValueARM_OpEqPtr_0(v)
|
return rewriteValueARM_OpEqPtr_0(v)
|
||||||
case OpFma:
|
case OpFMA:
|
||||||
return rewriteValueARM_OpFma_0(v)
|
return rewriteValueARM_OpFMA_0(v)
|
||||||
case OpGeq16:
|
case OpGeq16:
|
||||||
return rewriteValueARM_OpGeq16_0(v)
|
return rewriteValueARM_OpGeq16_0(v)
|
||||||
case OpGeq16U:
|
case OpGeq16U:
|
||||||
@ -17161,8 +17161,8 @@ func rewriteValueARM_OpEqPtr_0(v *Value) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func rewriteValueARM_OpFma_0(v *Value) bool {
|
func rewriteValueARM_OpFMA_0(v *Value) bool {
|
||||||
// match: (Fma x y z)
|
// match: (FMA x y z)
|
||||||
// result: (FMULAD z x y)
|
// result: (FMULAD z x y)
|
||||||
for {
|
for {
|
||||||
z := v.Args[2]
|
z := v.Args[2]
|
||||||
|
@ -573,8 +573,8 @@ func rewriteValueARM64(v *Value) bool {
|
|||||||
return rewriteValueARM64_OpEqPtr_0(v)
|
return rewriteValueARM64_OpEqPtr_0(v)
|
||||||
case OpFloor:
|
case OpFloor:
|
||||||
return rewriteValueARM64_OpFloor_0(v)
|
return rewriteValueARM64_OpFloor_0(v)
|
||||||
case OpFma:
|
case OpFMA:
|
||||||
return rewriteValueARM64_OpFma_0(v)
|
return rewriteValueARM64_OpFMA_0(v)
|
||||||
case OpGeq16:
|
case OpGeq16:
|
||||||
return rewriteValueARM64_OpGeq16_0(v)
|
return rewriteValueARM64_OpGeq16_0(v)
|
||||||
case OpGeq16U:
|
case OpGeq16U:
|
||||||
@ -28583,8 +28583,8 @@ func rewriteValueARM64_OpFloor_0(v *Value) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func rewriteValueARM64_OpFma_0(v *Value) bool {
|
func rewriteValueARM64_OpFMA_0(v *Value) bool {
|
||||||
// match: (Fma x y z)
|
// match: (FMA x y z)
|
||||||
// result: (FMADDD z x y)
|
// result: (FMADDD z x y)
|
||||||
for {
|
for {
|
||||||
z := v.Args[2]
|
z := v.Args[2]
|
||||||
|
@ -183,8 +183,8 @@ func rewriteValuePPC64(v *Value) bool {
|
|||||||
return rewriteValuePPC64_OpEqPtr_0(v)
|
return rewriteValuePPC64_OpEqPtr_0(v)
|
||||||
case OpFloor:
|
case OpFloor:
|
||||||
return rewriteValuePPC64_OpFloor_0(v)
|
return rewriteValuePPC64_OpFloor_0(v)
|
||||||
case OpFma:
|
case OpFMA:
|
||||||
return rewriteValuePPC64_OpFma_0(v)
|
return rewriteValuePPC64_OpFMA_0(v)
|
||||||
case OpGeq16:
|
case OpGeq16:
|
||||||
return rewriteValuePPC64_OpGeq16_0(v)
|
return rewriteValuePPC64_OpGeq16_0(v)
|
||||||
case OpGeq16U:
|
case OpGeq16U:
|
||||||
@ -2007,8 +2007,8 @@ func rewriteValuePPC64_OpFloor_0(v *Value) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func rewriteValuePPC64_OpFma_0(v *Value) bool {
|
func rewriteValuePPC64_OpFMA_0(v *Value) bool {
|
||||||
// match: (Fma x y z)
|
// match: (FMA x y z)
|
||||||
// result: (FMADD x y z)
|
// result: (FMADD x y z)
|
||||||
for {
|
for {
|
||||||
z := v.Args[2]
|
z := v.Args[2]
|
||||||
|
@ -168,8 +168,8 @@ func rewriteValueS390X(v *Value) bool {
|
|||||||
return rewriteValueS390X_OpEqPtr_0(v)
|
return rewriteValueS390X_OpEqPtr_0(v)
|
||||||
case OpFloor:
|
case OpFloor:
|
||||||
return rewriteValueS390X_OpFloor_0(v)
|
return rewriteValueS390X_OpFloor_0(v)
|
||||||
case OpFma:
|
case OpFMA:
|
||||||
return rewriteValueS390X_OpFma_0(v)
|
return rewriteValueS390X_OpFMA_0(v)
|
||||||
case OpGeq16:
|
case OpGeq16:
|
||||||
return rewriteValueS390X_OpGeq16_0(v)
|
return rewriteValueS390X_OpGeq16_0(v)
|
||||||
case OpGeq16U:
|
case OpGeq16U:
|
||||||
@ -1939,8 +1939,8 @@ func rewriteValueS390X_OpFloor_0(v *Value) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func rewriteValueS390X_OpFma_0(v *Value) bool {
|
func rewriteValueS390X_OpFMA_0(v *Value) bool {
|
||||||
// match: (Fma x y z)
|
// match: (FMA x y z)
|
||||||
// result: (FMADD z x y)
|
// result: (FMADD z x y)
|
||||||
for {
|
for {
|
||||||
z := v.Args[2]
|
z := v.Args[2]
|
||||||
|
@ -3053,11 +3053,11 @@ func TestYn(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFma(t *testing.T) {
|
func TestFMA(t *testing.T) {
|
||||||
for _, c := range fmaC {
|
for _, c := range fmaC {
|
||||||
got := Fma(c.x, c.y, c.z)
|
got := FMA(c.x, c.y, c.z)
|
||||||
if !alike(got, c.want) {
|
if !alike(got, c.want) {
|
||||||
t.Errorf("Fma(%g,%g,%g) == %g; want %g", c.x, c.y, c.z, got, c.want)
|
t.Errorf("FMA(%g,%g,%g) == %g; want %g", c.x, c.y, c.z, got, c.want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3793,10 +3793,10 @@ func BenchmarkFloat32frombits(b *testing.B) {
|
|||||||
GlobalF = float64(x)
|
GlobalF = float64(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkFma(b *testing.B) {
|
func BenchmarkFMA(b *testing.B) {
|
||||||
x := 0.0
|
x := 0.0
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
x = Fma(E, Pi, x)
|
x = FMA(E, Pi, x)
|
||||||
}
|
}
|
||||||
GlobalF = x
|
GlobalF = x
|
||||||
}
|
}
|
||||||
|
@ -90,8 +90,9 @@ func split(b uint64) (sign uint32, exp int32, mantissa uint64) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fma returns x * y + z, computed with only one rounding.
|
// FMA returns x * y + z, computed with only one rounding.
|
||||||
func Fma(x, y, z float64) float64 {
|
// (That is, FMA returns the fused multiply-add of x, y, and z.)
|
||||||
|
func FMA(x, y, z float64) float64 {
|
||||||
bx, by, bz := Float64bits(x), Float64bits(y), Float64bits(z)
|
bx, by, bz := Float64bits(x), Float64bits(y), Float64bits(z)
|
||||||
|
|
||||||
// Inf or NaN or zero involved. At most one rounding will occur.
|
// Inf or NaN or zero involved. At most one rounding will occur.
|
||||||
|
@ -114,7 +114,7 @@ func fma(x, y, z float64) float64 {
|
|||||||
// s390x:"FMADD"
|
// s390x:"FMADD"
|
||||||
// ppc64:"FMADD"
|
// ppc64:"FMADD"
|
||||||
// ppc64le:"FMADD"
|
// ppc64le:"FMADD"
|
||||||
return math.Fma(x, y, z)
|
return math.FMA(x, y, z)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromFloat64(f64 float64) uint64 {
|
func fromFloat64(f64 float64) uint64 {
|
||||||
|
Loading…
Reference in New Issue
Block a user