]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: intrinsify math.RoundToEven on s390x
authorMichael Munday <mike.munday@ibm.com>
Mon, 30 Oct 2017 13:02:44 +0000 (09:02 -0400)
committerMichael Munday <mike.munday@ibm.com>
Tue, 31 Oct 2017 18:04:27 +0000 (18:04 +0000)
The new RoundToEven function can be implemented as a single FIDBR
instruction on s390x.

name         old time/op  new time/op  delta
RoundToEven  5.32ns ± 1%  0.86ns ± 1%  -83.86%  (p=0.000 n=10+10)

Change-Id: Iaf597e57a0d1085961701e3c75ff4f6f6dcebb5f
Reviewed-on: https://go-review.googlesource.com/74350
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/asm_test.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/ssa/gen/S390X.rules
src/cmd/compile/internal/ssa/gen/genericOps.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteS390X.go

index 4320628f63975e7d28272824acbe054ff6e336b6..c609e0088fafbe411615564b6885372e39782ed4 100644 (file)
@@ -1633,6 +1633,14 @@ var linuxS390XTests = []*asmTest{
                `,
                pos: []string{"\tFIDBR\t[$]5"},
        },
+       {
+               fn: `
+               func roundToEven(x float64) float64 {
+                       return math.RoundToEven(x)
+               }
+               `,
+               pos: []string{"\tFIDBR\t[$]4"},
+       },
        {
                // check that stack store is optimized away
                fn: `
index 9eeeb35599e51bacc73c087293c69cc10a857b9b..233c639ba08a118ac78ad68f9cf931bac5247318 100644 (file)
@@ -2807,6 +2807,11 @@ func init() {
                        return s.newValue1(ssa.OpRound, types.Types[TFLOAT64], args[0])
                },
                sys.S390X)
+       addF("math", "RoundToEven",
+               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpRoundToEven, types.Types[TFLOAT64], args[0])
+               },
+               sys.S390X)
        addF("math", "Abs",
                func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
                        return s.newValue1(ssa.OpAbs, types.Types[TFLOAT64], args[0])
index 21bd7285081631db8fbb5a7f5d12dc112cedb040..a3908e7a8734acc94ac0ea4399b862e0743c02a4 100644 (file)
 (Bswap32 x) -> (MOVWBR x)
 
 // math package intrinsics
-(Sqrt  x) -> (FSQRT x)
-(Floor x) -> (FIDBR [7] x)
-(Ceil  x) -> (FIDBR [6] x)
-(Trunc x) -> (FIDBR [5] x)
-(Round x) -> (FIDBR [1] x)
+(Sqrt        x) -> (FSQRT x)
+(Floor       x) -> (FIDBR [7] x)
+(Ceil        x) -> (FIDBR [6] x)
+(Trunc       x) -> (FIDBR [5] x)
+(RoundToEven x) -> (FIDBR [4] x)
+(Round       x) -> (FIDBR [1] x)
 
 // Atomic loads.
 (AtomicLoad32 ptr mem) -> (MOVWZatomicload ptr mem)
index 0ad582b04617a0033837058f00d1cd14e95b00fb..d36910e7da1b718a85c78e243b0942b0ab9e50e3 100644 (file)
@@ -268,10 +268,11 @@ var genericOps = []opData{
        //   ±∞  → ±∞ (sign preserved)
        //   ±0  → ±0 (sign preserved)
        //   NaN → NaN
-       {name: "Floor", argLength: 1}, // round arg0 toward -∞
-       {name: "Ceil", argLength: 1},  // round arg0 toward +∞
-       {name: "Trunc", argLength: 1}, // round arg0 toward 0
-       {name: "Round", argLength: 1}, // round arg0 to nearest, ties away from 0
+       {name: "Floor", argLength: 1},       // round arg0 toward -∞
+       {name: "Ceil", argLength: 1},        // round arg0 toward +∞
+       {name: "Trunc", argLength: 1},       // round arg0 toward 0
+       {name: "Round", argLength: 1},       // round arg0 to nearest, ties away from 0
+       {name: "RoundToEven", argLength: 1}, // round arg0 to nearest, ties to even
 
        // Modify the sign bit
        {name: "Abs", argLength: 1},      // absolute value arg0
index a18cf78e88bea4f71151f746d0a8fee82be89b91..9d44e1ab84c46019e79fc112bb9615dfca496888 100644 (file)
@@ -1901,6 +1901,7 @@ const (
        OpCeil
        OpTrunc
        OpRound
+       OpRoundToEven
        OpAbs
        OpCopysign
        OpPhi
@@ -23318,6 +23319,11 @@ var opcodeTable = [...]opInfo{
                argLen:  1,
                generic: true,
        },
+       {
+               name:    "RoundToEven",
+               argLen:  1,
+               generic: true,
+       },
        {
                name:    "Abs",
                argLen:  1,
index 9237bfc4fcc23cd92a67218b20a437a7a6f35fde..0c7dd17f4a16ee0afcff00f1492e54821434ae2e 100644 (file)
@@ -383,6 +383,8 @@ func rewriteValueS390X(v *Value) bool {
                return rewriteValueS390X_OpRound32F_0(v)
        case OpRound64F:
                return rewriteValueS390X_OpRound64F_0(v)
+       case OpRoundToEven:
+               return rewriteValueS390X_OpRoundToEven_0(v)
        case OpRsh16Ux16:
                return rewriteValueS390X_OpRsh16Ux16_0(v)
        case OpRsh16Ux32:
@@ -5028,6 +5030,18 @@ func rewriteValueS390X_OpRound64F_0(v *Value) bool {
                return true
        }
 }
+func rewriteValueS390X_OpRoundToEven_0(v *Value) bool {
+       // match: (RoundToEven x)
+       // cond:
+       // result: (FIDBR [4] x)
+       for {
+               x := v.Args[0]
+               v.reset(OpS390XFIDBR)
+               v.AuxInt = 4
+               v.AddArg(x)
+               return true
+       }
+}
 func rewriteValueS390X_OpRsh16Ux16_0(v *Value) bool {
        b := v.Block
        _ = b