Skip to content

Commit

Permalink
cmd/compile: simplify shifts when the counter fits 6 bits.
Browse files Browse the repository at this point in the history
In f the extra & 63 is redundant because SHRQ already
looks at the bottom 6 bits only. This is a trick on AMD64
to get rid of CMPQ/SBBQ/ANDQ if one knows that the shift
counter is small.

func f(x uint64, s uint) uint64 {
        return x >> (s & 63)
}

Change-Id: I4861c902168dabec9a6a14a85750246dde94fc08
Reviewed-on: https://go-review.googlesource.com/21073
Reviewed-by: Keith Randall <[email protected]>
Run-TryBot: Alexandru Moșoi <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
  • Loading branch information
Alexandru Moșoi authored and brtzsnr committed Mar 24, 2016
1 parent d8ee180 commit afafab3
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/cmd/compile/internal/ssa/gen/AMD64.rules
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,21 @@
(SARB x (MOVWconst [c])) -> (SARBconst [c&31] x)
(SARB x (MOVBconst [c])) -> (SARBconst [c&31] x)

(SARB x (ANDBconst [31] y)) -> (SARB x y)
(SARW x (ANDWconst [31] y)) -> (SARW x y)
(SARL x (ANDLconst [31] y)) -> (SARL x y)
(SARQ x (ANDQconst [63] y)) -> (SARQ x y)

(SHLB x (ANDBconst [31] y)) -> (SHLB x y)
(SHLW x (ANDWconst [31] y)) -> (SHLW x y)
(SHLL x (ANDLconst [31] y)) -> (SHLL x y)
(SHLQ x (ANDQconst [63] y)) -> (SHLQ x y)

(SHRB x (ANDBconst [31] y)) -> (SHRB x y)
(SHRW x (ANDWconst [31] y)) -> (SHRW x y)
(SHRL x (ANDLconst [31] y)) -> (SHRL x y)
(SHRQ x (ANDQconst [63] y)) -> (SHRQ x y)

// Note: the word and byte shifts keep the low 5 bits (not the low 4 or 3 bits)
// because the x86 instructions are defined to use all 5 bits of the shift even
// for the small shifts. I don't think we'll ever generate a weird shift (e.g.
Expand Down
216 changes: 216 additions & 0 deletions src/cmd/compile/internal/ssa/rewriteAMD64.go
Original file line number Diff line number Diff line change
Expand Up @@ -11781,6 +11781,24 @@ func rewriteValueAMD64_OpAMD64SARB(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SARB x (ANDBconst [31] y))
// cond:
// result: (SARB x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDBconst {
break
}
if v_1.AuxInt != 31 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SARB)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SARBconst(v *Value, config *Config) bool {
Expand Down Expand Up @@ -11865,6 +11883,24 @@ func rewriteValueAMD64_OpAMD64SARL(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SARL x (ANDLconst [31] y))
// cond:
// result: (SARL x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDLconst {
break
}
if v_1.AuxInt != 31 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SARL)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SARLconst(v *Value, config *Config) bool {
Expand Down Expand Up @@ -11949,6 +11985,24 @@ func rewriteValueAMD64_OpAMD64SARQ(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SARQ x (ANDQconst [63] y))
// cond:
// result: (SARQ x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDQconst {
break
}
if v_1.AuxInt != 63 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SARQ)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SARQconst(v *Value, config *Config) bool {
Expand Down Expand Up @@ -12033,6 +12087,24 @@ func rewriteValueAMD64_OpAMD64SARW(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SARW x (ANDWconst [31] y))
// cond:
// result: (SARW x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDWconst {
break
}
if v_1.AuxInt != 31 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SARW)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SARWconst(v *Value, config *Config) bool {
Expand Down Expand Up @@ -13027,6 +13099,24 @@ func rewriteValueAMD64_OpAMD64SHLB(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SHLB x (ANDBconst [31] y))
// cond:
// result: (SHLB x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDBconst {
break
}
if v_1.AuxInt != 31 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SHLB)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SHLL(v *Value, config *Config) bool {
Expand Down Expand Up @@ -13092,6 +13182,24 @@ func rewriteValueAMD64_OpAMD64SHLL(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SHLL x (ANDLconst [31] y))
// cond:
// result: (SHLL x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDLconst {
break
}
if v_1.AuxInt != 31 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SHLL)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SHLQ(v *Value, config *Config) bool {
Expand Down Expand Up @@ -13157,6 +13265,24 @@ func rewriteValueAMD64_OpAMD64SHLQ(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SHLQ x (ANDQconst [63] y))
// cond:
// result: (SHLQ x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDQconst {
break
}
if v_1.AuxInt != 63 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SHLQ)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SHLW(v *Value, config *Config) bool {
Expand Down Expand Up @@ -13222,6 +13348,24 @@ func rewriteValueAMD64_OpAMD64SHLW(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SHLW x (ANDWconst [31] y))
// cond:
// result: (SHLW x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDWconst {
break
}
if v_1.AuxInt != 31 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SHLW)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SHRB(v *Value, config *Config) bool {
Expand Down Expand Up @@ -13287,6 +13431,24 @@ func rewriteValueAMD64_OpAMD64SHRB(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SHRB x (ANDBconst [31] y))
// cond:
// result: (SHRB x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDBconst {
break
}
if v_1.AuxInt != 31 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SHRB)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SHRL(v *Value, config *Config) bool {
Expand Down Expand Up @@ -13352,6 +13514,24 @@ func rewriteValueAMD64_OpAMD64SHRL(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SHRL x (ANDLconst [31] y))
// cond:
// result: (SHRL x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDLconst {
break
}
if v_1.AuxInt != 31 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SHRL)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SHRQ(v *Value, config *Config) bool {
Expand Down Expand Up @@ -13417,6 +13597,24 @@ func rewriteValueAMD64_OpAMD64SHRQ(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SHRQ x (ANDQconst [63] y))
// cond:
// result: (SHRQ x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDQconst {
break
}
if v_1.AuxInt != 63 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SHRQ)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SHRW(v *Value, config *Config) bool {
Expand Down Expand Up @@ -13482,6 +13680,24 @@ func rewriteValueAMD64_OpAMD64SHRW(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (SHRW x (ANDWconst [31] y))
// cond:
// result: (SHRW x y)
for {
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpAMD64ANDWconst {
break
}
if v_1.AuxInt != 31 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64SHRW)
v.AddArg(x)
v.AddArg(y)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64SUBB(v *Value, config *Config) bool {
Expand Down

0 comments on commit afafab3

Please sign in to comment.