mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile/internal/ssa: make oneBit function generic
Allows rewrite rules using oneBit to be made more compact. Change-Id: I986715f77db5b548759d809fe668e1893048f25c Reviewed-on: https://go-review.googlesource.com/c/go/+/699295 Reviewed-by: Youlin Feng <fengyoulin@live.com> Commit-Queue: Keith Randall <khr@golang.org> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
fe42628dae
commit
84b070bfb1
3 changed files with 24 additions and 37 deletions
|
|
@ -1896,22 +1896,10 @@
|
||||||
(Neq(8|16|32|64) s:(Sub(8|16|32|64) x y) (Const(8|16|32|64) [0])) && s.Uses == 1 => (Neq(8|16|32|64) x y)
|
(Neq(8|16|32|64) s:(Sub(8|16|32|64) x y) (Const(8|16|32|64) [0])) && s.Uses == 1 => (Neq(8|16|32|64) x y)
|
||||||
|
|
||||||
// Optimize bitsets
|
// Optimize bitsets
|
||||||
(Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y])) && oneBit8(y)
|
(Eq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [y])) && oneBit(y)
|
||||||
=> (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
|
=> (Neq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [0]))
|
||||||
(Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y])) && oneBit16(y)
|
(Neq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [y])) && oneBit(y)
|
||||||
=> (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
|
=> (Eq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [0]))
|
||||||
(Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y])) && oneBit32(y)
|
|
||||||
=> (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
|
|
||||||
(Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y])) && oneBit64(y)
|
|
||||||
=> (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
|
|
||||||
(Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y])) && oneBit8(y)
|
|
||||||
=> (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
|
|
||||||
(Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y])) && oneBit16(y)
|
|
||||||
=> (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
|
|
||||||
(Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y])) && oneBit32(y)
|
|
||||||
=> (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
|
|
||||||
(Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y])) && oneBit64(y)
|
|
||||||
=> (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
|
|
||||||
|
|
||||||
// Reassociate expressions involving
|
// Reassociate expressions involving
|
||||||
// constants such that constants come first,
|
// constants such that constants come first,
|
||||||
|
|
|
||||||
|
|
@ -470,11 +470,10 @@ func ntz32(x int32) int { return bits.TrailingZeros32(uint32(x)) }
|
||||||
func ntz16(x int16) int { return bits.TrailingZeros16(uint16(x)) }
|
func ntz16(x int16) int { return bits.TrailingZeros16(uint16(x)) }
|
||||||
func ntz8(x int8) int { return bits.TrailingZeros8(uint8(x)) }
|
func ntz8(x int8) int { return bits.TrailingZeros8(uint8(x)) }
|
||||||
|
|
||||||
func oneBit(x int64) bool { return x&(x-1) == 0 && x != 0 }
|
// oneBit reports whether x contains exactly one set bit.
|
||||||
func oneBit8(x int8) bool { return x&(x-1) == 0 && x != 0 }
|
func oneBit[T int8 | int16 | int32 | int64](x T) bool {
|
||||||
func oneBit16(x int16) bool { return x&(x-1) == 0 && x != 0 }
|
return x&(x-1) == 0 && x != 0
|
||||||
func oneBit32(x int32) bool { return x&(x-1) == 0 && x != 0 }
|
}
|
||||||
func oneBit64(x int64) bool { return x&(x-1) == 0 && x != 0 }
|
|
||||||
|
|
||||||
// nto returns the number of trailing ones.
|
// nto returns the number of trailing ones.
|
||||||
func nto(x int64) int64 {
|
func nto(x int64) int64 {
|
||||||
|
|
|
||||||
|
|
@ -8796,7 +8796,7 @@ func rewriteValuegeneric_OpEq16(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// match: (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y]))
|
// match: (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y]))
|
||||||
// cond: oneBit16(y)
|
// cond: oneBit(y)
|
||||||
// result: (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
|
// result: (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
|
|
@ -8813,7 +8813,7 @@ func rewriteValuegeneric_OpEq16(v *Value) bool {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
y := auxIntToInt16(v_0_1.AuxInt)
|
y := auxIntToInt16(v_0_1.AuxInt)
|
||||||
if v_1.Op != OpConst16 || v_1.Type != t || auxIntToInt16(v_1.AuxInt) != y || !(oneBit16(y)) {
|
if v_1.Op != OpConst16 || v_1.Type != t || auxIntToInt16(v_1.AuxInt) != y || !(oneBit(y)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpNeq16)
|
v.reset(OpNeq16)
|
||||||
|
|
@ -9660,7 +9660,7 @@ func rewriteValuegeneric_OpEq32(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// match: (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y]))
|
// match: (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y]))
|
||||||
// cond: oneBit32(y)
|
// cond: oneBit(y)
|
||||||
// result: (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
|
// result: (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
|
|
@ -9677,7 +9677,7 @@ func rewriteValuegeneric_OpEq32(v *Value) bool {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
y := auxIntToInt32(v_0_1.AuxInt)
|
y := auxIntToInt32(v_0_1.AuxInt)
|
||||||
if v_1.Op != OpConst32 || v_1.Type != t || auxIntToInt32(v_1.AuxInt) != y || !(oneBit32(y)) {
|
if v_1.Op != OpConst32 || v_1.Type != t || auxIntToInt32(v_1.AuxInt) != y || !(oneBit(y)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpNeq32)
|
v.reset(OpNeq32)
|
||||||
|
|
@ -10241,7 +10241,7 @@ func rewriteValuegeneric_OpEq64(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// match: (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y]))
|
// match: (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y]))
|
||||||
// cond: oneBit64(y)
|
// cond: oneBit(y)
|
||||||
// result: (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
|
// result: (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
|
|
@ -10258,7 +10258,7 @@ func rewriteValuegeneric_OpEq64(v *Value) bool {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
y := auxIntToInt64(v_0_1.AuxInt)
|
y := auxIntToInt64(v_0_1.AuxInt)
|
||||||
if v_1.Op != OpConst64 || v_1.Type != t || auxIntToInt64(v_1.AuxInt) != y || !(oneBit64(y)) {
|
if v_1.Op != OpConst64 || v_1.Type != t || auxIntToInt64(v_1.AuxInt) != y || !(oneBit(y)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpNeq64)
|
v.reset(OpNeq64)
|
||||||
|
|
@ -10663,7 +10663,7 @@ func rewriteValuegeneric_OpEq8(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// match: (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y]))
|
// match: (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y]))
|
||||||
// cond: oneBit8(y)
|
// cond: oneBit(y)
|
||||||
// result: (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
|
// result: (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
|
|
@ -10680,7 +10680,7 @@ func rewriteValuegeneric_OpEq8(v *Value) bool {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
y := auxIntToInt8(v_0_1.AuxInt)
|
y := auxIntToInt8(v_0_1.AuxInt)
|
||||||
if v_1.Op != OpConst8 || v_1.Type != t || auxIntToInt8(v_1.AuxInt) != y || !(oneBit8(y)) {
|
if v_1.Op != OpConst8 || v_1.Type != t || auxIntToInt8(v_1.AuxInt) != y || !(oneBit(y)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpNeq8)
|
v.reset(OpNeq8)
|
||||||
|
|
@ -20309,7 +20309,7 @@ func rewriteValuegeneric_OpNeq16(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// match: (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y]))
|
// match: (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y]))
|
||||||
// cond: oneBit16(y)
|
// cond: oneBit(y)
|
||||||
// result: (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
|
// result: (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
|
|
@ -20326,7 +20326,7 @@ func rewriteValuegeneric_OpNeq16(v *Value) bool {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
y := auxIntToInt16(v_0_1.AuxInt)
|
y := auxIntToInt16(v_0_1.AuxInt)
|
||||||
if v_1.Op != OpConst16 || v_1.Type != t || auxIntToInt16(v_1.AuxInt) != y || !(oneBit16(y)) {
|
if v_1.Op != OpConst16 || v_1.Type != t || auxIntToInt16(v_1.AuxInt) != y || !(oneBit(y)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpEq16)
|
v.reset(OpEq16)
|
||||||
|
|
@ -20496,7 +20496,7 @@ func rewriteValuegeneric_OpNeq32(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// match: (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y]))
|
// match: (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y]))
|
||||||
// cond: oneBit32(y)
|
// cond: oneBit(y)
|
||||||
// result: (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
|
// result: (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
|
|
@ -20513,7 +20513,7 @@ func rewriteValuegeneric_OpNeq32(v *Value) bool {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
y := auxIntToInt32(v_0_1.AuxInt)
|
y := auxIntToInt32(v_0_1.AuxInt)
|
||||||
if v_1.Op != OpConst32 || v_1.Type != t || auxIntToInt32(v_1.AuxInt) != y || !(oneBit32(y)) {
|
if v_1.Op != OpConst32 || v_1.Type != t || auxIntToInt32(v_1.AuxInt) != y || !(oneBit(y)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpEq32)
|
v.reset(OpEq32)
|
||||||
|
|
@ -20706,7 +20706,7 @@ func rewriteValuegeneric_OpNeq64(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// match: (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y]))
|
// match: (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y]))
|
||||||
// cond: oneBit64(y)
|
// cond: oneBit(y)
|
||||||
// result: (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
|
// result: (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
|
|
@ -20723,7 +20723,7 @@ func rewriteValuegeneric_OpNeq64(v *Value) bool {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
y := auxIntToInt64(v_0_1.AuxInt)
|
y := auxIntToInt64(v_0_1.AuxInt)
|
||||||
if v_1.Op != OpConst64 || v_1.Type != t || auxIntToInt64(v_1.AuxInt) != y || !(oneBit64(y)) {
|
if v_1.Op != OpConst64 || v_1.Type != t || auxIntToInt64(v_1.AuxInt) != y || !(oneBit(y)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpEq64)
|
v.reset(OpEq64)
|
||||||
|
|
@ -20916,7 +20916,7 @@ func rewriteValuegeneric_OpNeq8(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// match: (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y]))
|
// match: (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y]))
|
||||||
// cond: oneBit8(y)
|
// cond: oneBit(y)
|
||||||
// result: (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
|
// result: (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
|
|
@ -20933,7 +20933,7 @@ func rewriteValuegeneric_OpNeq8(v *Value) bool {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
y := auxIntToInt8(v_0_1.AuxInt)
|
y := auxIntToInt8(v_0_1.AuxInt)
|
||||||
if v_1.Op != OpConst8 || v_1.Type != t || auxIntToInt8(v_1.AuxInt) != y || !(oneBit8(y)) {
|
if v_1.Op != OpConst8 || v_1.Type != t || auxIntToInt8(v_1.AuxInt) != y || !(oneBit(y)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpEq8)
|
v.reset(OpEq8)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue