From: Michael Munday Date: Tue, 26 Aug 2025 21:12:29 +0000 (+0100) Subject: cmd/compile/internal/ssa: make oneBit function generic X-Git-Tag: go1.26rc1~992 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=84b070bfb1;p=gostls13.git 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 Commit-Queue: Keith Randall Auto-Submit: Keith Randall Reviewed-by: Keith Randall Reviewed-by: Keith Randall Reviewed-by: Cherry Mui LUCI-TryBot-Result: Go LUCI --- diff --git a/src/cmd/compile/internal/ssa/_gen/generic.rules b/src/cmd/compile/internal/ssa/_gen/generic.rules index 7ac36c3b3c..da112abbf5 100644 --- a/src/cmd/compile/internal/ssa/_gen/generic.rules +++ b/src/cmd/compile/internal/ssa/_gen/generic.rules @@ -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) // Optimize bitsets -(Eq8 (And8 x (Const8 [y])) (Const8 [y])) && oneBit8(y) - => (Neq8 (And8 x (Const8 [y])) (Const8 [0])) -(Eq16 (And16 x (Const16 [y])) (Const16 [y])) && oneBit16(y) - => (Neq16 (And16 x (Const16 [y])) (Const16 [0])) -(Eq32 (And32 x (Const32 [y])) (Const32 [y])) && oneBit32(y) - => (Neq32 (And32 x (Const32 [y])) (Const32 [0])) -(Eq64 (And64 x (Const64 [y])) (Const64 [y])) && oneBit64(y) - => (Neq64 (And64 x (Const64 [y])) (Const64 [0])) -(Neq8 (And8 x (Const8 [y])) (Const8 [y])) && oneBit8(y) - => (Eq8 (And8 x (Const8 [y])) (Const8 [0])) -(Neq16 (And16 x (Const16 [y])) (Const16 [y])) && oneBit16(y) - => (Eq16 (And16 x (Const16 [y])) (Const16 [0])) -(Neq32 (And32 x (Const32 [y])) (Const32 [y])) && oneBit32(y) - => (Eq32 (And32 x (Const32 [y])) (Const32 [0])) -(Neq64 (And64 x (Const64 [y])) (Const64 [y])) && oneBit64(y) - => (Eq64 (And64 x (Const64 [y])) (Const64 [0])) +(Eq(8|16|32|64) (And(8|16|32|64) x (Const(8|16|32|64) [y])) (Const(8|16|32|64) [y])) && oneBit(y) + => (Neq(8|16|32|64) (And(8|16|32|64) x (Const(8|16|32|64) [y])) (Const(8|16|32|64) [0])) +(Neq(8|16|32|64) (And(8|16|32|64) x (Const(8|16|32|64) [y])) (Const(8|16|32|64) [y])) && oneBit(y) + => (Eq(8|16|32|64) (And(8|16|32|64) x (Const(8|16|32|64) [y])) (Const(8|16|32|64) [0])) // Reassociate expressions involving // constants such that constants come first, diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index 236a3f885a..6704c7d6e0 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -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 ntz8(x int8) int { return bits.TrailingZeros8(uint8(x)) } -func oneBit(x int64) bool { return x&(x-1) == 0 && x != 0 } -func oneBit8(x int8) bool { return x&(x-1) == 0 && x != 0 } -func oneBit16(x int16) bool { 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 } +// oneBit reports whether x contains exactly one set bit. +func oneBit[T int8 | int16 | int32 | int64](x T) bool { + return x&(x-1) == 0 && x != 0 +} // nto returns the number of trailing ones. func nto(x int64) int64 { diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index 3af7f40e68..5394747ba5 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -8796,7 +8796,7 @@ func rewriteValuegeneric_OpEq16(v *Value) bool { break } // match: (Eq16 (And16 x (Const16 [y])) (Const16 [y])) - // cond: oneBit16(y) + // cond: oneBit(y) // result: (Neq16 (And16 x (Const16 [y])) (Const16 [0])) for { 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 } 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 } v.reset(OpNeq16) @@ -9660,7 +9660,7 @@ func rewriteValuegeneric_OpEq32(v *Value) bool { break } // match: (Eq32 (And32 x (Const32 [y])) (Const32 [y])) - // cond: oneBit32(y) + // cond: oneBit(y) // result: (Neq32 (And32 x (Const32 [y])) (Const32 [0])) for { 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 } 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 } v.reset(OpNeq32) @@ -10241,7 +10241,7 @@ func rewriteValuegeneric_OpEq64(v *Value) bool { break } // match: (Eq64 (And64 x (Const64 [y])) (Const64 [y])) - // cond: oneBit64(y) + // cond: oneBit(y) // result: (Neq64 (And64 x (Const64 [y])) (Const64 [0])) for { 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 } 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 } v.reset(OpNeq64) @@ -10663,7 +10663,7 @@ func rewriteValuegeneric_OpEq8(v *Value) bool { break } // match: (Eq8 (And8 x (Const8 [y])) (Const8 [y])) - // cond: oneBit8(y) + // cond: oneBit(y) // result: (Neq8 (And8 x (Const8 [y])) (Const8 [0])) for { 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 } 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 } v.reset(OpNeq8) @@ -20309,7 +20309,7 @@ func rewriteValuegeneric_OpNeq16(v *Value) bool { break } // match: (Neq16 (And16 x (Const16 [y])) (Const16 [y])) - // cond: oneBit16(y) + // cond: oneBit(y) // result: (Eq16 (And16 x (Const16 [y])) (Const16 [0])) for { 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 } 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 } v.reset(OpEq16) @@ -20496,7 +20496,7 @@ func rewriteValuegeneric_OpNeq32(v *Value) bool { break } // match: (Neq32 (And32 x (Const32 [y])) (Const32 [y])) - // cond: oneBit32(y) + // cond: oneBit(y) // result: (Eq32 (And32 x (Const32 [y])) (Const32 [0])) for { 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 } 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 } v.reset(OpEq32) @@ -20706,7 +20706,7 @@ func rewriteValuegeneric_OpNeq64(v *Value) bool { break } // match: (Neq64 (And64 x (Const64 [y])) (Const64 [y])) - // cond: oneBit64(y) + // cond: oneBit(y) // result: (Eq64 (And64 x (Const64 [y])) (Const64 [0])) for { 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 } 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 } v.reset(OpEq64) @@ -20916,7 +20916,7 @@ func rewriteValuegeneric_OpNeq8(v *Value) bool { break } // match: (Neq8 (And8 x (Const8 [y])) (Const8 [y])) - // cond: oneBit8(y) + // cond: oneBit(y) // result: (Eq8 (And8 x (Const8 [y])) (Const8 [0])) for { 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 } 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 } v.reset(OpEq8)