From: Cherry Zhang Date: Thu, 6 Apr 2017 13:36:23 +0000 (-0400) Subject: cmd/compile: use ANDconst to mask out leading/trailing bits on ARM64 X-Git-Tag: go1.9beta1~815 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=257b01f8f47ace2ddd75efe37d8a0353888bce14;p=gostls13.git cmd/compile: use ANDconst to mask out leading/trailing bits on ARM64 For an AND that masks out leading or trailing bits, generic rules rewrite it to a pair of shifts. On ARM64, the mask actually can fit into an AND instruction. So we rewrite it back to AND. Fixes #19857. Change-Id: I479d7320ae4f29bb3f0056d5979bde4478063a8f Reviewed-on: https://go-review.googlesource.com/39651 Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot Reviewed-by: David Chase --- diff --git a/src/cmd/compile/internal/gc/asm_test.go b/src/cmd/compile/internal/gc/asm_test.go index dd96bec282..6c56b8d8e5 100644 --- a/src/cmd/compile/internal/gc/asm_test.go +++ b/src/cmd/compile/internal/gc/asm_test.go @@ -1327,6 +1327,22 @@ var linuxARM64Tests = []*asmTest{ `, []string{"\tCLZ\t"}, }, + { + ` + func f34(a uint64) uint64 { + return a & ((1<<63)-1) + } + `, + []string{"\tAND\t"}, + }, + { + ` + func f35(a uint64) uint64 { + return a & (1<<63) + } + `, + []string{"\tAND\t"}, + }, } var linuxMIPSTests = []*asmTest{ diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules index 8f7680a347..189e739434 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM64.rules +++ b/src/cmd/compile/internal/ssa/gen/ARM64.rules @@ -1148,8 +1148,11 @@ ( ORshiftRL [c] (SLLconst x [32-c]) (MOVWUreg x)) && c < 32 && t.Size() == 4 -> (RORWconst [ c] x) (XORshiftRL [c] (SLLconst x [32-c]) (MOVWUreg x)) && c < 32 && t.Size() == 4 -> (RORWconst [ c] x) -// Replace SRL-of-SLL with ROR-of-SLL to avoid hardware bug. -(SRLconst [c] y:(SLLconst [c] _)) && c <= 8 -> (RORconst [c] y) +// Generic rules rewrite certain AND to a pair of shifts. +// However, on ARM64 the bitmask can fit into an instruction. +// Rewrite it back to AND. +(SRLconst [c] (SLLconst [c] x)) && 0 < c && c < 64 -> (ANDconst [1< (ANDconst [^(1<> uint64(c)) return true } - // match: (SRLconst [c] y:(SLLconst [c] _)) - // cond: c <= 8 - // result: (RORconst [c] y) + // match: (SRLconst [c] (SLLconst [c] x)) + // cond: 0 < c && c < 64 + // result: (ANDconst [1<