Skip to content

Commit dd91269

Browse files
erifan01cherrymui
authored andcommitted
cmd/compile: optimize math/bits Len32 intrinsic on arm64
Arm64 has a 32-bit CLZ instruction CLZW, which can be used for intrinsic Len32. Function LeadingZeros32 calls Len32, with this change, the assembly code of LeadingZeros32 becomes more concise. Go code: func f32(x uint32) { z = bits.LeadingZeros32(x) } Before: "".f32 STEXT size=32 args=0x8 locals=0x0 leaf 0x0000 00000 (test.go:7) TEXT "".f32(SB), LEAF|NOFRAME|ABIInternal, $0-8 0x0004 00004 (test.go:7) MOVWU "".x(FP), R0 0x0008 00008 ($GOROOT/src/math/bits/bits.go:30) CLZ R0, R0 0x000c 00012 ($GOROOT/src/math/bits/bits.go:30) SUB $32, R0, R0 0x0010 00016 (test.go:7) MOVD R0, "".z(SB) 0x001c 00028 (test.go:7) RET (R30) After: "".f32 STEXT size=32 args=0x8 locals=0x0 leaf 0x0000 00000 (test.go:7) TEXT "".f32(SB), LEAF|NOFRAME|ABIInternal, $0-8 0x0004 00004 (test.go:7) MOVWU "".x(FP), R0 0x0008 00008 ($GOROOT/src/math/bits/bits.go:30) CLZW R0, R0 0x000c 00012 (test.go:7) MOVD R0, "".z(SB) 0x0018 00024 (test.go:7) RET (R30) Benchmarks: name old time/op new time/op delta LeadingZeros-8 2.53ns ± 0% 2.55ns ± 0% +0.67% (p=0.000 n=10+10) LeadingZeros8-8 3.56ns ± 0% 3.56ns ± 0% ~ (all equal) LeadingZeros16-8 3.55ns ± 0% 3.56ns ± 0% ~ (p=0.465 n=10+10) LeadingZeros32-8 3.55ns ± 0% 2.96ns ± 0% -16.71% (p=0.000 n=10+7) LeadingZeros64-8 2.53ns ± 0% 2.54ns ± 0% ~ (p=0.059 n=8+10) Change-Id: Ie5666bb82909e341060e02ffd4e86c0e5d67e90a Reviewed-on: https://go-review.googlesource.com/c/157000 Run-TryBot: Cherry Zhang <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Cherry Zhang <[email protected]>
1 parent f40cb19 commit dd91269

File tree

4 files changed

+26
-3
lines changed

4 files changed

+26
-3
lines changed

src/cmd/compile/internal/gc/ssa.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3327,7 +3327,7 @@ func init() {
33273327
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
33283328
return s.newValue1(ssa.OpBitLen32, types.Types[TINT], args[0])
33293329
},
3330-
sys.AMD64)
3330+
sys.AMD64, sys.ARM64)
33313331
addF("math/bits", "Len32",
33323332
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
33333333
if s.config.PtrSize == 4 {
@@ -3336,7 +3336,7 @@ func init() {
33363336
x := s.newValue1(ssa.OpZeroExt32to64, types.Types[TUINT64], args[0])
33373337
return s.newValue1(ssa.OpBitLen64, types.Types[TINT], x)
33383338
},
3339-
sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64)
3339+
sys.ARM, sys.S390X, sys.MIPS, sys.PPC64)
33403340
addF("math/bits", "Len16",
33413341
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
33423342
if s.config.PtrSize == 4 {

src/cmd/compile/internal/ssa/gen/ARM64.rules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
(FMOVSload [off] {sym} ptr (MOVWstore [off] {sym} ptr val _)) -> (FMOVSgpfp val)
124124

125125
(BitLen64 x) -> (SUB (MOVDconst [64]) (CLZ <typ.Int> x))
126+
(BitLen32 x) -> (SUB (MOVDconst [32]) (CLZW <typ.Int> x))
126127

127128
(Bswap64 x) -> (REV x)
128129
(Bswap32 x) -> (REVW x)

src/cmd/compile/internal/ssa/rewriteARM64.go

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/codegen/mathbits.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func LeadingZeros64(n uint64) int {
3131
func LeadingZeros32(n uint32) int {
3232
// amd64:"BSRQ","LEAQ",-"CMOVQEQ"
3333
// s390x:"FLOGR"
34-
// arm:"CLZ" arm64:"CLZ"
34+
// arm:"CLZ" arm64:"CLZW"
3535
// mips:"CLZ"
3636
return bits.LeadingZeros32(n)
3737
}

0 commit comments

Comments
 (0)