]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: use unsigned power-of-two detector for unsigned mod
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 23 Jul 2025 16:51:16 +0000 (23:51 +0700)
committerGopher Robot <gobot@golang.org>
Tue, 29 Jul 2025 23:22:40 +0000 (16:22 -0700)
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>
src/cmd/compile/internal/ssa/_gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go
test/codegen/issue74485.go

index 533dd96d8b0d363109f05ae2f9f6e1b37fd976a3..7ac36c3b3cd3911ad07cf9a21d3737b562ae655f 100644 (file)
       (Const64 <typ.UInt64> [63])))
 
 // Unsigned mod by power of 2 constant.
-(Mod8u  <t> n (Const8  [c])) && isPowerOfTwo(c) => (And8  n (Const8  <t> [c-1]))
-(Mod16u <t> n (Const16 [c])) && isPowerOfTwo(c) => (And16 n (Const16 <t> [c-1]))
-(Mod32u <t> n (Const32 [c])) && isPowerOfTwo(c) => (And32 n (Const32 <t> [c-1]))
-(Mod64u <t> n (Const64 [c])) && isPowerOfTwo(c) => (And64 n (Const64 <t> [c-1]))
-(Mod64u <t> n (Const64 [-1<<63]))                 => (And64 n (Const64 <t> [1<<63-1]))
+(Mod8u  <t> n (Const8  [c])) && isUnsignedPowerOfTwo(uint8(c)) => (And8  n (Const8  <t> [c-1]))
+(Mod16u <t> n (Const16 [c])) && isUnsignedPowerOfTwo(uint16(c)) => (And16 n (Const16 <t> [c-1]))
+(Mod32u <t> n (Const32 [c])) && isUnsignedPowerOfTwo(uint32(c)) => (And32 n (Const32 <t> [c-1]))
+(Mod64u <t> n (Const64 [c])) && isUnsignedPowerOfTwo(uint64(c)) => (And64 n (Const64 <t> [c-1]))
 
 // Signed non-negative mod by power of 2 constant.
 (Mod8  <t> n (Const8  [c])) && isNonNegative(n) && isPowerOfTwo(c) => (And8  n (Const8  <t> [c-1]))
index 9303b96822014060caa0c2abe231e30d14d45e4a..3af7f40e684f912f5a74a12173add3c5209a7f82 100644 (file)
@@ -16906,7 +16906,7 @@ func rewriteValuegeneric_OpMod16u(v *Value) bool {
                return true
        }
        // match: (Mod16u <t> n (Const16 [c]))
-       // cond: isPowerOfTwo(c)
+       // cond: isUnsignedPowerOfTwo(uint16(c))
        // result: (And16 n (Const16 <t> [c-1]))
        for {
                t := v.Type
@@ -16915,7 +16915,7 @@ func rewriteValuegeneric_OpMod16u(v *Value) bool {
                        break
                }
                c := auxIntToInt16(v_1.AuxInt)
-               if !(isPowerOfTwo(c)) {
+               if !(isUnsignedPowerOfTwo(uint16(c))) {
                        break
                }
                v.reset(OpAnd16)
@@ -17060,7 +17060,7 @@ func rewriteValuegeneric_OpMod32u(v *Value) bool {
                return true
        }
        // match: (Mod32u <t> n (Const32 [c]))
-       // cond: isPowerOfTwo(c)
+       // cond: isUnsignedPowerOfTwo(uint32(c))
        // result: (And32 n (Const32 <t> [c-1]))
        for {
                t := v.Type
@@ -17069,7 +17069,7 @@ func rewriteValuegeneric_OpMod32u(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_1.AuxInt)
-               if !(isPowerOfTwo(c)) {
+               if !(isUnsignedPowerOfTwo(uint32(c))) {
                        break
                }
                v.reset(OpAnd32)
@@ -17225,7 +17225,7 @@ func rewriteValuegeneric_OpMod64u(v *Value) bool {
                return true
        }
        // match: (Mod64u <t> n (Const64 [c]))
-       // cond: isPowerOfTwo(c)
+       // cond: isUnsignedPowerOfTwo(uint64(c))
        // result: (And64 n (Const64 <t> [c-1]))
        for {
                t := v.Type
@@ -17234,7 +17234,7 @@ func rewriteValuegeneric_OpMod64u(v *Value) bool {
                        break
                }
                c := auxIntToInt64(v_1.AuxInt)
-               if !(isPowerOfTwo(c)) {
+               if !(isUnsignedPowerOfTwo(uint64(c))) {
                        break
                }
                v.reset(OpAnd64)
@@ -17243,20 +17243,6 @@ func rewriteValuegeneric_OpMod64u(v *Value) bool {
                v.AddArg2(n, v0)
                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]))
        // cond: x.Op != OpConst64 && c > 0 && umagicOK64(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
        }
        // match: (Mod8u <t> n (Const8 [c]))
-       // cond: isPowerOfTwo(c)
+       // cond: isUnsignedPowerOfTwo(uint8(c))
        // result: (And8 n (Const8 <t> [c-1]))
        for {
                t := v.Type
@@ -17402,7 +17388,7 @@ func rewriteValuegeneric_OpMod8u(v *Value) bool {
                        break
                }
                c := auxIntToInt8(v_1.AuxInt)
-               if !(isPowerOfTwo(c)) {
+               if !(isUnsignedPowerOfTwo(uint8(c))) {
                        break
                }
                v.reset(OpAnd8)
index 570707509b73e131e34c373dd0e53b8691fb100f..b5aba9568caca7ac992c65a5a65fb35ede048b35 100644 (file)
@@ -25,3 +25,23 @@ func divUint8(b uint8) uint8 {
        // amd64:"SHRB  [$]7, AL"
        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
+}