Skip to content

Commit

Permalink
cmd/compile: optimize RotateLeft8/16 on arm64
Browse files Browse the repository at this point in the history
This CL optimizes RotateLeft8/16 on arm64.

For 16 bits, we form a 32 bits register by duplicating two 16 bits
registers, then use RORW instruction to do the rotate shift.

For 8 bits, we just use LSR and LSL instead of RORW because the code is
simpler.

Benchmark          Old          ThisCL       delta
RotateLeft8-46     2.16 ns/op   1.73 ns/op   -19.70%
RotateLeft16-46    2.16 ns/op   1.54 ns/op   -28.53%

Change-Id: I09cde4383d12e31876a57f8cdfd3bb4f324fadb0
Reviewed-on: https://go-review.googlesource.com/c/go/+/420976
Reviewed-by: Keith Randall <[email protected]>
Auto-Submit: Keith Randall <[email protected]>
Reviewed-by: Keith Randall <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Reviewed-by: Heschi Kreinick <[email protected]>
Run-TryBot: Keith Randall <[email protected]>
  • Loading branch information
RuinanSun authored and gopherbot committed Sep 2, 2022
1 parent f45c2d7 commit 121344a
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 8 deletions.
3 changes: 3 additions & 0 deletions src/cmd/compile/internal/ssa/gen/ARM64.rules
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@
(Sqrt32 ...) => (FSQRTS ...)

// lowering rotates
// we do rotate detection in generic rules, if the following rules need to be changed, chcek generic rules first.
(RotateLeft8 <t> x (MOVDconst [c])) => (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
(RotateLeft8 <t> x y) => (OR <t> (SLL <t> x (ANDconst <typ.Int64> [7] y)) (SRL <t> (ZeroExt8to64 x) (ANDconst <typ.Int64> [7] (NEG <typ.Int64> y))))
(RotateLeft16 <t> x (MOVDconst [c])) => (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
(RotateLeft16 <t> x y) => (RORW <t> (ORshiftLL <typ.UInt32> (ZeroExt16to32 x) (ZeroExt16to32 x) [16]) (NEG <typ.Int64> y))
(RotateLeft32 x y) => (RORW x (NEG <y.Type> y))
(RotateLeft64 x y) => (ROR x (NEG <y.Type> y))

Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/ssa/rewrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -1986,9 +1986,9 @@ func canRotate(c *Config, bits int64) bool {
return false
}
switch c.arch {
case "386", "amd64":
case "386", "amd64", "arm64":
return true
case "arm", "arm64", "s390x", "ppc64", "ppc64le", "wasm", "loong64":
case "arm", "s390x", "ppc64", "ppc64le", "wasm", "loong64":
return bits >= 32
default:
return false
Expand Down
45 changes: 43 additions & 2 deletions src/cmd/compile/internal/ssa/rewriteARM64.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions test/codegen/mathbits.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,16 @@ func RotateLeft32(n uint32) uint32 {
return bits.RotateLeft32(n, 9)
}

func RotateLeft16(n uint16) uint16 {
func RotateLeft16(n uint16, s int) uint16 {
// amd64:"ROLW" 386:"ROLW"
return bits.RotateLeft16(n, 5)
// arm64:"RORW",-"CSEL"
return bits.RotateLeft16(n, s)
}

func RotateLeft8(n uint8) uint8 {
func RotateLeft8(n uint8, s int) uint8 {
// amd64:"ROLB" 386:"ROLB"
return bits.RotateLeft8(n, 5)
// arm64:"LSL","LSR",-"CSEL"
return bits.RotateLeft8(n, s)
}

func RotateLeftVariable(n uint, m int) uint {
Expand Down

0 comments on commit 121344a

Please sign in to comment.