From: Carlos Eduardo Seo Date: Fri, 22 Feb 2019 19:12:37 +0000 (-0300) Subject: cmd/compile: make math/bits.RotateLeft{32,64} intrinsics on ppc64x X-Git-Tag: go1.13beta1~1037 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=f2a18b1456e9cbb83ada13776195c56d2a6fb951;p=gostls13.git cmd/compile: make math/bits.RotateLeft{32,64} intrinsics on ppc64x Extends CL 132435 to ppc64x. ppc64x has 32- and 64-bit variable rotate left instructions. name old time/op new time/op delta RotateLeft32-16 1.39ns ± 0% 1.37ns ± 0% -1.44% (p=0.008 n=5+5) RotateLeft64-16 1.35ns ± 0% 1.32ns ± 0% -2.22% (p=0.008 n=5+5) Updates #17566 Change-Id: I567f634ff90d0691db45df0a25c99fcdfe10ca00 Reviewed-on: https://go-review.googlesource.com/c/go/+/163760 Reviewed-by: Lynn Boger --- diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index ecc449114d..d61f463ccf 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -3427,12 +3427,12 @@ func init() { func(s *state, n *Node, args []*ssa.Value) *ssa.Value { return s.newValue2(ssa.OpRotateLeft32, types.Types[TUINT32], args[0], args[1]) }, - sys.AMD64, sys.ARM64, sys.S390X) + sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64) addF("math/bits", "RotateLeft64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { return s.newValue2(ssa.OpRotateLeft64, types.Types[TUINT64], args[0], args[1]) }, - sys.AMD64, sys.ARM64, sys.S390X) + sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64) alias("math/bits", "RotateLeft", "math/bits", "RotateLeft64", p8...) makeOnesCountAMD64 := func(op64 ssa.Op, op32 ssa.Op) func(s *state, n *Node, args []*ssa.Value) *ssa.Value { diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules index e5d5295908..8dee5a1cba 100644 --- a/src/cmd/compile/internal/ssa/gen/PPC64.rules +++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules @@ -100,6 +100,14 @@ ( OR (SLW x (ANDconst [31] y)) (SRW x (SUB (MOVDconst [32]) (ANDconst [31] y)))) -> (ROTLW x y) (XOR (SLW x (ANDconst [31] y)) (SRW x (SUB (MOVDconst [32]) (ANDconst [31] y)))) -> (ROTLW x y) +// Lowering rotates +(RotateLeft32 x y) -> (ROTLW x y) +(RotateLeft64 x y) -> (ROTL x y) + +// Constant rotate generation +(ROTLW x (MOVDconst [c])) -> (ROTLWconst x [c&31]) +(ROTL x (MOVDconst [c])) -> (ROTLconst x [c&63]) + (Lsh64x64 x (Const64 [c])) && uint64(c) < 64 -> (SLDconst x [c]) (Rsh64x64 x (Const64 [c])) && uint64(c) < 64 -> (SRADconst x [c]) (Rsh64Ux64 x (Const64 [c])) && uint64(c) < 64 -> (SRDconst x [c]) diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go index 302b785f61..9245f403b8 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -537,6 +537,10 @@ func rewriteValuePPC64(v *Value) bool { return rewriteValuePPC64_OpPPC64ORN_0(v) case OpPPC64ORconst: return rewriteValuePPC64_OpPPC64ORconst_0(v) + case OpPPC64ROTL: + return rewriteValuePPC64_OpPPC64ROTL_0(v) + case OpPPC64ROTLW: + return rewriteValuePPC64_OpPPC64ROTLW_0(v) case OpPPC64SUB: return rewriteValuePPC64_OpPPC64SUB_0(v) case OpPPC64XOR: @@ -551,6 +555,10 @@ func rewriteValuePPC64(v *Value) bool { return rewriteValuePPC64_OpPopCount64_0(v) case OpPopCount8: return rewriteValuePPC64_OpPopCount8_0(v) + case OpRotateLeft32: + return rewriteValuePPC64_OpRotateLeft32_0(v) + case OpRotateLeft64: + return rewriteValuePPC64_OpRotateLeft64_0(v) case OpRound: return rewriteValuePPC64_OpRound_0(v) case OpRound32F: @@ -25533,6 +25541,44 @@ func rewriteValuePPC64_OpPPC64ORconst_0(v *Value) bool { } return false } +func rewriteValuePPC64_OpPPC64ROTL_0(v *Value) bool { + // match: (ROTL x (MOVDconst [c])) + // cond: + // result: (ROTLconst x [c&63]) + for { + _ = v.Args[1] + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVDconst { + break + } + c := v_1.AuxInt + v.reset(OpPPC64ROTLconst) + v.AuxInt = c & 63 + v.AddArg(x) + return true + } + return false +} +func rewriteValuePPC64_OpPPC64ROTLW_0(v *Value) bool { + // match: (ROTLW x (MOVDconst [c])) + // cond: + // result: (ROTLWconst x [c&31]) + for { + _ = v.Args[1] + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVDconst { + break + } + c := v_1.AuxInt + v.reset(OpPPC64ROTLWconst) + v.AuxInt = c & 31 + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64SUB_0(v *Value) bool { // match: (SUB x (MOVDconst [c])) // cond: is32Bit(-c) @@ -26086,6 +26132,34 @@ func rewriteValuePPC64_OpPopCount8_0(v *Value) bool { return true } } +func rewriteValuePPC64_OpRotateLeft32_0(v *Value) bool { + // match: (RotateLeft32 x y) + // cond: + // result: (ROTLW x y) + for { + _ = v.Args[1] + x := v.Args[0] + y := v.Args[1] + v.reset(OpPPC64ROTLW) + v.AddArg(x) + v.AddArg(y) + return true + } +} +func rewriteValuePPC64_OpRotateLeft64_0(v *Value) bool { + // match: (RotateLeft64 x y) + // cond: + // result: (ROTL x y) + for { + _ = v.Args[1] + x := v.Args[0] + y := v.Args[1] + v.reset(OpPPC64ROTL) + v.AddArg(x) + v.AddArg(y) + return true + } +} func rewriteValuePPC64_OpRound_0(v *Value) bool { // match: (Round x) // cond: