1
0
mirror of https://github.com/golang/go synced 2024-09-30 05:34:35 -06:00

cmd/compile: rewrite upper-bit-clear idiom to use shift-rotate

Old buggy hardware incorrectly executes the shift-left-K
then shift-right-K idiom for clearing K leftmost bits.
Use a right rotate instead of shift to avoid triggering the
bug.

Fixes #19809.

Change-Id: I6dc646b183c29e9d01aef944729f34388dcc687d
Reviewed-on: https://go-review.googlesource.com/39310
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
David Chase 2017-04-03 11:50:54 -04:00
parent d6b999436a
commit 9d5987d79f
2 changed files with 23 additions and 0 deletions

View File

@ -1190,6 +1190,9 @@
( ORshiftRL <t> [c] (SLLconst x [32-c]) (MOVWUreg x)) && c < 32 && t.Size() == 4 -> (RORWconst [ c] x)
(XORshiftRL <t> [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)
// do combined loads
// little endian loads
// b[0] | b[1]<<8 -> load 16-bit

View File

@ -8094,6 +8094,26 @@ func rewriteValueARM64_OpARM64SRLconst(v *Value) bool {
v.AuxInt = int64(uint64(d) >> uint64(c))
return true
}
// match: (SRLconst [c] y:(SLLconst [c] _))
// cond: c <= 8
// result: (RORconst [c] y)
for {
c := v.AuxInt
y := v.Args[0]
if y.Op != OpARM64SLLconst {
break
}
if y.AuxInt != c {
break
}
if !(c <= 8) {
break
}
v.reset(OpARM64RORconst)
v.AuxInt = c
v.AddArg(y)
return true
}
return false
}
func rewriteValueARM64_OpARM64SUB(v *Value) bool {