]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: guard the &-to-<<>> opt against small constants
authorDavid Chase <drchase@google.com>
Tue, 8 Mar 2016 20:08:25 +0000 (15:08 -0500)
committerDavid Chase <drchase@google.com>
Tue, 8 Mar 2016 23:06:11 +0000 (23:06 +0000)
Converting an and-K into a pair of shifts for K that will
fit in a one-byte argument is probably not an optimization,
and it also interferes with other patterns that we want to
see fire, like (<< (AND K)) [for small K] and bounds check
elimination for masked indices.

Turns out that on Intel, even 32-bit signed immediates beat
the shift pair; the size reduction of tool binaries is 0.09%
vs 0.07% for only the 8-bit immediates.

RLH found this one working on the new/next GC.

Change-Id: I2414a8de1dd58d680d18587577fbadb7ff4f67d9
Reviewed-on: https://go-review.googlesource.com/20410
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: David Chase <drchase@google.com>

src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go

index 57ab70339a7449dc9dc2ae933df8e78638a7e892..8cb79a0da846088a62c0d7217424458a84e27b69 100644 (file)
 (Trunc32to16 (And32 (Const32 [y]) x)) && y&0xFFFF == 0xFFFF -> (Trunc32to16 x)
 (Trunc16to8 (And16 (Const16 [y]) x)) && y&0xFF == 0xFF -> (Trunc16to8 x)
 
-// Rewrite AND of consts as shifts if possible, slightly faster for 32/64 bit operands
+// Rewrite AND of consts as shifts if possible, slightly faster for 64 bit operands
 // leading zeros can be shifted left, then right
-(And64 <t> (Const64 [y]) x) && nlz(y) + nto(y) == 64 -> (Rsh64Ux64 (Lsh64x64 <t> x (Const64 <t> [nlz(y)])) (Const64 <t> [nlz(y)]))
-(And32 <t> (Const32 [y]) x) && nlz(int64(int32(y))) + nto(int64(int32(y))) == 64 -> (Rsh32Ux32 (Lsh32x32 <t> x (Const32 <t> [nlz(int64(int32(y)))-32])) (Const32 <t> [nlz(int64(int32(y)))-32]))
+(And64 <t> (Const64 [y]) x) && nlz(y) + nto(y) == 64 && nto(y) >= 32 -> (Rsh64Ux64 (Lsh64x64 <t> x (Const64 <t> [nlz(y)])) (Const64 <t> [nlz(y)]))
 // trailing zeros can be shifted right, then left
-(And64 <t> (Const64 [y]) x) && nlo(y) + ntz(y) == 64 -> (Lsh64x64 (Rsh64Ux64 <t> x (Const64 <t> [ntz(y)])) (Const64 <t> [ntz(y)]))
-(And32 <t> (Const32 [y]) x) && nlo(int64(int32(y))) + ntz(int64(int32(y))) == 64 -> (Lsh32x32 (Rsh32Ux32 <t> x (Const32 <t> [ntz(int64(int32(y)))])) (Const32 <t> [ntz(int64(int32(y)))]))
+(And64 <t> (Const64 [y]) x) && nlo(y) + ntz(y) == 64 && ntz(y) >= 32 -> (Lsh64x64 (Rsh64Ux64 <t> x (Const64 <t> [ntz(y)])) (Const64 <t> [ntz(y)]))
 
 // simplifications often used for lengths.  e.g. len(s[i:i+5])==5
 (Sub64 (Add64 x y) x) -> y
index cde60c1bcd288d329d901f74c7d04258aff9165c..122c661114312699d82676d05508f15a347d197d 100644 (file)
@@ -693,56 +693,6 @@ func rewriteValuegeneric_OpAnd32(v *Value, config *Config) bool {
                v.AuxInt = 0
                return true
        }
-       // match: (And32 <t> (Const32 [y]) x)
-       // cond: nlz(int64(int32(y))) + nto(int64(int32(y))) == 64
-       // result: (Rsh32Ux32 (Lsh32x32 <t> x (Const32 <t> [nlz(int64(int32(y)))-32])) (Const32 <t> [nlz(int64(int32(y)))-32]))
-       for {
-               t := v.Type
-               if v.Args[0].Op != OpConst32 {
-                       break
-               }
-               y := v.Args[0].AuxInt
-               x := v.Args[1]
-               if !(nlz(int64(int32(y)))+nto(int64(int32(y))) == 64) {
-                       break
-               }
-               v.reset(OpRsh32Ux32)
-               v0 := b.NewValue0(v.Line, OpLsh32x32, t)
-               v0.AddArg(x)
-               v1 := b.NewValue0(v.Line, OpConst32, t)
-               v1.AuxInt = nlz(int64(int32(y))) - 32
-               v0.AddArg(v1)
-               v.AddArg(v0)
-               v2 := b.NewValue0(v.Line, OpConst32, t)
-               v2.AuxInt = nlz(int64(int32(y))) - 32
-               v.AddArg(v2)
-               return true
-       }
-       // match: (And32 <t> (Const32 [y]) x)
-       // cond: nlo(int64(int32(y))) + ntz(int64(int32(y))) == 64
-       // result: (Lsh32x32 (Rsh32Ux32 <t> x (Const32 <t> [ntz(int64(int32(y)))])) (Const32 <t> [ntz(int64(int32(y)))]))
-       for {
-               t := v.Type
-               if v.Args[0].Op != OpConst32 {
-                       break
-               }
-               y := v.Args[0].AuxInt
-               x := v.Args[1]
-               if !(nlo(int64(int32(y)))+ntz(int64(int32(y))) == 64) {
-                       break
-               }
-               v.reset(OpLsh32x32)
-               v0 := b.NewValue0(v.Line, OpRsh32Ux32, t)
-               v0.AddArg(x)
-               v1 := b.NewValue0(v.Line, OpConst32, t)
-               v1.AuxInt = ntz(int64(int32(y)))
-               v0.AddArg(v1)
-               v.AddArg(v0)
-               v2 := b.NewValue0(v.Line, OpConst32, t)
-               v2.AuxInt = ntz(int64(int32(y)))
-               v.AddArg(v2)
-               return true
-       }
        return false
 }
 func rewriteValuegeneric_OpAnd64(v *Value, config *Config) bool {
@@ -812,7 +762,7 @@ func rewriteValuegeneric_OpAnd64(v *Value, config *Config) bool {
                return true
        }
        // match: (And64 <t> (Const64 [y]) x)
-       // cond: nlz(y) + nto(y) == 64
+       // cond: nlz(y) + nto(y) == 64 && nto(y) >= 32
        // result: (Rsh64Ux64 (Lsh64x64 <t> x (Const64 <t> [nlz(y)])) (Const64 <t> [nlz(y)]))
        for {
                t := v.Type
@@ -821,7 +771,7 @@ func rewriteValuegeneric_OpAnd64(v *Value, config *Config) bool {
                }
                y := v.Args[0].AuxInt
                x := v.Args[1]
-               if !(nlz(y)+nto(y) == 64) {
+               if !(nlz(y)+nto(y) == 64 && nto(y) >= 32) {
                        break
                }
                v.reset(OpRsh64Ux64)
@@ -837,7 +787,7 @@ func rewriteValuegeneric_OpAnd64(v *Value, config *Config) bool {
                return true
        }
        // match: (And64 <t> (Const64 [y]) x)
-       // cond: nlo(y) + ntz(y) == 64
+       // cond: nlo(y) + ntz(y) == 64 && ntz(y) >= 32
        // result: (Lsh64x64 (Rsh64Ux64 <t> x (Const64 <t> [ntz(y)])) (Const64 <t> [ntz(y)]))
        for {
                t := v.Type
@@ -846,7 +796,7 @@ func rewriteValuegeneric_OpAnd64(v *Value, config *Config) bool {
                }
                y := v.Args[0].AuxInt
                x := v.Args[1]
-               if !(nlo(y)+ntz(y) == 64) {
+               if !(nlo(y)+ntz(y) == 64 && ntz(y) >= 32) {
                        break
                }
                v.reset(OpLsh64x64)