mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: use unsigned power-of-two detector for unsigned mod
Same as CL 689815, but for modulus instead of division. Updates #74485 Change-Id: I73000231c886a987a1093669ff207fd9117a8160 Reviewed-on: https://go-review.googlesource.com/c/go/+/689895 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
f3582fc80e
commit
bd94ae8903
3 changed files with 32 additions and 27 deletions
|
|
@ -1293,11 +1293,10 @@
|
||||||
(Const64 <typ.UInt64> [63])))
|
(Const64 <typ.UInt64> [63])))
|
||||||
|
|
||||||
// Unsigned mod by power of 2 constant.
|
// Unsigned mod by power of 2 constant.
|
||||||
(Mod8u <t> n (Const8 [c])) && isPowerOfTwo(c) => (And8 n (Const8 <t> [c-1]))
|
(Mod8u <t> n (Const8 [c])) && isUnsignedPowerOfTwo(uint8(c)) => (And8 n (Const8 <t> [c-1]))
|
||||||
(Mod16u <t> n (Const16 [c])) && isPowerOfTwo(c) => (And16 n (Const16 <t> [c-1]))
|
(Mod16u <t> n (Const16 [c])) && isUnsignedPowerOfTwo(uint16(c)) => (And16 n (Const16 <t> [c-1]))
|
||||||
(Mod32u <t> n (Const32 [c])) && isPowerOfTwo(c) => (And32 n (Const32 <t> [c-1]))
|
(Mod32u <t> n (Const32 [c])) && isUnsignedPowerOfTwo(uint32(c)) => (And32 n (Const32 <t> [c-1]))
|
||||||
(Mod64u <t> n (Const64 [c])) && isPowerOfTwo(c) => (And64 n (Const64 <t> [c-1]))
|
(Mod64u <t> n (Const64 [c])) && isUnsignedPowerOfTwo(uint64(c)) => (And64 n (Const64 <t> [c-1]))
|
||||||
(Mod64u <t> n (Const64 [-1<<63])) => (And64 n (Const64 <t> [1<<63-1]))
|
|
||||||
|
|
||||||
// Signed non-negative mod by power of 2 constant.
|
// Signed non-negative mod by power of 2 constant.
|
||||||
(Mod8 <t> n (Const8 [c])) && isNonNegative(n) && isPowerOfTwo(c) => (And8 n (Const8 <t> [c-1]))
|
(Mod8 <t> n (Const8 [c])) && isNonNegative(n) && isPowerOfTwo(c) => (And8 n (Const8 <t> [c-1]))
|
||||||
|
|
|
||||||
|
|
@ -16906,7 +16906,7 @@ func rewriteValuegeneric_OpMod16u(v *Value) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (Mod16u <t> n (Const16 [c]))
|
// match: (Mod16u <t> n (Const16 [c]))
|
||||||
// cond: isPowerOfTwo(c)
|
// cond: isUnsignedPowerOfTwo(uint16(c))
|
||||||
// result: (And16 n (Const16 <t> [c-1]))
|
// result: (And16 n (Const16 <t> [c-1]))
|
||||||
for {
|
for {
|
||||||
t := v.Type
|
t := v.Type
|
||||||
|
|
@ -16915,7 +16915,7 @@ func rewriteValuegeneric_OpMod16u(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c := auxIntToInt16(v_1.AuxInt)
|
c := auxIntToInt16(v_1.AuxInt)
|
||||||
if !(isPowerOfTwo(c)) {
|
if !(isUnsignedPowerOfTwo(uint16(c))) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
v.reset(OpAnd16)
|
v.reset(OpAnd16)
|
||||||
|
|
@ -17060,7 +17060,7 @@ func rewriteValuegeneric_OpMod32u(v *Value) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (Mod32u <t> n (Const32 [c]))
|
// match: (Mod32u <t> n (Const32 [c]))
|
||||||
// cond: isPowerOfTwo(c)
|
// cond: isUnsignedPowerOfTwo(uint32(c))
|
||||||
// result: (And32 n (Const32 <t> [c-1]))
|
// result: (And32 n (Const32 <t> [c-1]))
|
||||||
for {
|
for {
|
||||||
t := v.Type
|
t := v.Type
|
||||||
|
|
@ -17069,7 +17069,7 @@ func rewriteValuegeneric_OpMod32u(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c := auxIntToInt32(v_1.AuxInt)
|
c := auxIntToInt32(v_1.AuxInt)
|
||||||
if !(isPowerOfTwo(c)) {
|
if !(isUnsignedPowerOfTwo(uint32(c))) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
v.reset(OpAnd32)
|
v.reset(OpAnd32)
|
||||||
|
|
@ -17225,7 +17225,7 @@ func rewriteValuegeneric_OpMod64u(v *Value) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (Mod64u <t> n (Const64 [c]))
|
// match: (Mod64u <t> n (Const64 [c]))
|
||||||
// cond: isPowerOfTwo(c)
|
// cond: isUnsignedPowerOfTwo(uint64(c))
|
||||||
// result: (And64 n (Const64 <t> [c-1]))
|
// result: (And64 n (Const64 <t> [c-1]))
|
||||||
for {
|
for {
|
||||||
t := v.Type
|
t := v.Type
|
||||||
|
|
@ -17234,7 +17234,7 @@ func rewriteValuegeneric_OpMod64u(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c := auxIntToInt64(v_1.AuxInt)
|
c := auxIntToInt64(v_1.AuxInt)
|
||||||
if !(isPowerOfTwo(c)) {
|
if !(isUnsignedPowerOfTwo(uint64(c))) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
v.reset(OpAnd64)
|
v.reset(OpAnd64)
|
||||||
|
|
@ -17243,20 +17243,6 @@ func rewriteValuegeneric_OpMod64u(v *Value) bool {
|
||||||
v.AddArg2(n, v0)
|
v.AddArg2(n, v0)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (Mod64u <t> n (Const64 [-1<<63]))
|
|
||||||
// result: (And64 n (Const64 <t> [1<<63-1]))
|
|
||||||
for {
|
|
||||||
t := v.Type
|
|
||||||
n := v_0
|
|
||||||
if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != -1<<63 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
v.reset(OpAnd64)
|
|
||||||
v0 := b.NewValue0(v.Pos, OpConst64, t)
|
|
||||||
v0.AuxInt = int64ToAuxInt(1<<63 - 1)
|
|
||||||
v.AddArg2(n, v0)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// match: (Mod64u <t> x (Const64 [c]))
|
// match: (Mod64u <t> x (Const64 [c]))
|
||||||
// cond: x.Op != OpConst64 && c > 0 && umagicOK64(c)
|
// cond: x.Op != OpConst64 && c > 0 && umagicOK64(c)
|
||||||
// result: (Sub64 x (Mul64 <t> (Div64u <t> x (Const64 <t> [c])) (Const64 <t> [c])))
|
// result: (Sub64 x (Mul64 <t> (Div64u <t> x (Const64 <t> [c])) (Const64 <t> [c])))
|
||||||
|
|
@ -17393,7 +17379,7 @@ func rewriteValuegeneric_OpMod8u(v *Value) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (Mod8u <t> n (Const8 [c]))
|
// match: (Mod8u <t> n (Const8 [c]))
|
||||||
// cond: isPowerOfTwo(c)
|
// cond: isUnsignedPowerOfTwo(uint8(c))
|
||||||
// result: (And8 n (Const8 <t> [c-1]))
|
// result: (And8 n (Const8 <t> [c-1]))
|
||||||
for {
|
for {
|
||||||
t := v.Type
|
t := v.Type
|
||||||
|
|
@ -17402,7 +17388,7 @@ func rewriteValuegeneric_OpMod8u(v *Value) bool {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c := auxIntToInt8(v_1.AuxInt)
|
c := auxIntToInt8(v_1.AuxInt)
|
||||||
if !(isPowerOfTwo(c)) {
|
if !(isUnsignedPowerOfTwo(uint8(c))) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
v.reset(OpAnd8)
|
v.reset(OpAnd8)
|
||||||
|
|
|
||||||
|
|
@ -25,3 +25,23 @@ func divUint8(b uint8) uint8 {
|
||||||
// amd64:"SHRB [$]7, AL"
|
// amd64:"SHRB [$]7, AL"
|
||||||
return b / 128
|
return b / 128
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func modUint64(b uint64) uint64 {
|
||||||
|
// amd64:"BTRQ [$]63, AX"
|
||||||
|
return b % 9223372036854775808
|
||||||
|
}
|
||||||
|
|
||||||
|
func modUint32(b uint32) uint32 {
|
||||||
|
// amd64:"ANDL [$]2147483647, AX"
|
||||||
|
return b % 2147483648
|
||||||
|
}
|
||||||
|
|
||||||
|
func modUint16(b uint16) uint16 {
|
||||||
|
// amd64:"ANDL [$]32767, AX"
|
||||||
|
return b % 32768
|
||||||
|
}
|
||||||
|
|
||||||
|
func modUint8(b uint8) uint8 {
|
||||||
|
// amd64:"ANDL [$]127, AX"
|
||||||
|
return b % 128
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue