]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: intrinsify math.RoundToEven on amd64
authorIlya Tocar <ilya.tocar@intel.com>
Tue, 31 Oct 2017 21:49:27 +0000 (16:49 -0500)
committerIlya Tocar <ilya.tocar@intel.com>
Thu, 2 Nov 2017 17:33:52 +0000 (17:33 +0000)
We already do this for floor/ceil, but RoundToEven was added later.
Intrinsify it also.

name           old time/op  new time/op  delta
RoundToEven-8  3.00ns ± 1%  0.68ns ± 2%  -77.34%  (p=0.000 n=10+10)

Change-Id: Ib158cbceb436c6725b2d9353a526c5c4be19bcad
Reviewed-on: https://go-review.googlesource.com/74852
Run-TryBot: Ilya Tocar <ilya.tocar@intel.com>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/amd64/ssa.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/ssa/gen/AMD64.rules
src/cmd/compile/internal/ssa/rewriteAMD64.go

index 5bf8f0e4d8521a3e8a28b0cd1a2fb5508566cf58..ce322e5e9908e561692aaa09e9dd1f73cd033de0 100644 (file)
@@ -855,8 +855,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        case ssa.OpAMD64ROUNDSD:
                p := s.Prog(v.Op.Asm())
                val := v.AuxInt
-               // 1 means math.Floor, 2 Ceil, 3 Trunc
-               if val != 1 && val != 2 && val != 3 {
+               // 0 means math.RoundToEven, 1 Floor, 2 Ceil, 3 Trunc
+               if val != 0 && val != 1 && val != 2 && val != 3 {
                        v.Fatalf("Invalid rounding mode")
                }
                p.From.Offset = val
index 4bb88b62efddd9ae3519a8b66338a28263f07165..a02b2ec25f7cf196dd2611bc4eae296affe939a8 100644 (file)
@@ -2860,6 +2860,9 @@ func init() {
                        return s.variable(n, types.Types[TFLOAT64])
                }
        }
+       addF("math", "RoundToEven",
+               makeRoundAMD64(ssa.OpRoundToEven),
+               sys.AMD64)
        addF("math", "Floor",
                makeRoundAMD64(ssa.OpFloor),
                sys.AMD64)
index d26cdfba56fab7fe7ceaff07f1dbcbc009205de2..238515dfcb1e21be7fdd2369ab61a180fbf12936 100644 (file)
 
 (Sqrt x) -> (SQRTSD x)
 
-(Floor x) -> (ROUNDSD [1] x)
-(Ceil x)  -> (ROUNDSD [2] x)
-(Trunc x) -> (ROUNDSD [3] x)
+(RoundToEven x) -> (ROUNDSD [0] x)
+(Floor x)      -> (ROUNDSD [1] x)
+(Ceil x)       -> (ROUNDSD [2] x)
+(Trunc x)      -> (ROUNDSD [3] x)
 
 // Lowering extension
 // Note: we always extend to 64 bits even though some ops don't need that many result bits.
index e6f574b6c114d29d7b4eba2b37491db468c8680c..c54949fd9df2fd198a94bad5bcd23fd9ce170b01 100644 (file)
@@ -795,6 +795,8 @@ func rewriteValueAMD64(v *Value) bool {
                return rewriteValueAMD64_OpRound32F_0(v)
        case OpRound64F:
                return rewriteValueAMD64_OpRound64F_0(v)
+       case OpRoundToEven:
+               return rewriteValueAMD64_OpRoundToEven_0(v)
        case OpRsh16Ux16:
                return rewriteValueAMD64_OpRsh16Ux16_0(v)
        case OpRsh16Ux32:
@@ -45652,6 +45654,18 @@ func rewriteValueAMD64_OpRound64F_0(v *Value) bool {
                return true
        }
 }
+func rewriteValueAMD64_OpRoundToEven_0(v *Value) bool {
+       // match: (RoundToEven x)
+       // cond:
+       // result: (ROUNDSD [0] x)
+       for {
+               x := v.Args[0]
+               v.reset(OpAMD64ROUNDSD)
+               v.AuxInt = 0
+               v.AddArg(x)
+               return true
+       }
+}
 func rewriteValueAMD64_OpRsh16Ux16_0(v *Value) bool {
        b := v.Block
        _ = b