]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: rewrite upper-bit-clear idiom to use shift-rotate
authorDavid Chase <drchase@google.com>
Mon, 3 Apr 2017 15:50:54 +0000 (11:50 -0400)
committerDavid Chase <drchase@google.com>
Mon, 3 Apr 2017 17:16:23 +0000 (17:16 +0000)
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>
src/cmd/compile/internal/ssa/gen/ARM64.rules
src/cmd/compile/internal/ssa/rewriteARM64.go

index 41661082c7cd421953faaa89e565767f750e3fd6..a4d651604b236c01ba7a00f065b4244e4deb058e 100644 (file)
 ( 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
index d276cbcf103ac3017c0a520e500d755ad7c4c4f7..e7436e72f4fb5095049aace874af2a54bc5e18ae 100644 (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 {