Commit 9d5987d7 authored by David Chase's avatar David Chase

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: default avatarRuss Cox <rsc@golang.org>
parent d6b99943
......@@ -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
......
......@@ -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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment