]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add constant folding for PopCount
authorJorropo <jorropo.pgm@gmail.com>
Sun, 9 Mar 2025 09:21:06 +0000 (10:21 +0100)
committerGopher Robot <gobot@golang.org>
Tue, 11 Mar 2025 20:50:52 +0000 (13:50 -0700)
Change-Id: I6ea3f75ddd5c7af114ef77bc48f28c7f8570997b
Reviewed-on: https://go-review.googlesource.com/c/go/+/656156
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: David Chase <drchase@google.com>
Auto-Submit: Jorropo <jorropo.pgm@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/_gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go

index 8a54645feea30de7c6bf156d64785f9feca6b1d1..49696cea2a31e12832521860fb8cf76cf803b4d7 100644 (file)
 (BitLen32 (Const32 [c])) && config.PtrSize == 4 => (Const32 [int32(bits.Len32(uint32(c)))])
 (BitLen16 (Const16 [c])) && config.PtrSize == 4 => (Const32 [int32(bits.Len16(uint16(c)))])
 (BitLen8  (Const8  [c])) && config.PtrSize == 4 => (Const32 [int32(bits.Len8(uint8(c)))])
+(PopCount64 (Const64 [c])) && config.PtrSize == 8 => (Const64 [int64(bits.OnesCount64(uint64(c)))])
+(PopCount32 (Const32 [c])) && config.PtrSize == 8 => (Const64 [int64(bits.OnesCount32(uint32(c)))])
+(PopCount16 (Const16 [c])) && config.PtrSize == 8 => (Const64 [int64(bits.OnesCount16(uint16(c)))])
+(PopCount8  (Const8  [c])) && config.PtrSize == 8 => (Const64 [int64(bits.OnesCount8(uint8(c)))])
+(PopCount64 (Const64 [c])) && config.PtrSize == 4 => (Const32 [int32(bits.OnesCount64(uint64(c)))])
+(PopCount32 (Const32 [c])) && config.PtrSize == 4 => (Const32 [int32(bits.OnesCount32(uint32(c)))])
+(PopCount16 (Const16 [c])) && config.PtrSize == 4 => (Const32 [int32(bits.OnesCount16(uint16(c)))])
+(PopCount8  (Const8  [c])) && config.PtrSize == 4 => (Const32 [int32(bits.OnesCount8(uint8(c)))])
 
 (Trunc16to8  (ZeroExt8to16  x)) => x
 (Trunc32to8  (ZeroExt8to32  x)) => x
index 0cdaded87f15c767d47be7d2c104b6abc62144cd..b951ecdfc5a61de3d31ed6bd2eedba1d73afb394 100644 (file)
@@ -298,6 +298,14 @@ func rewriteValuegeneric(v *Value) bool {
                return rewriteValuegeneric_OpOrB(v)
        case OpPhi:
                return rewriteValuegeneric_OpPhi(v)
+       case OpPopCount16:
+               return rewriteValuegeneric_OpPopCount16(v)
+       case OpPopCount32:
+               return rewriteValuegeneric_OpPopCount32(v)
+       case OpPopCount64:
+               return rewriteValuegeneric_OpPopCount64(v)
+       case OpPopCount8:
+               return rewriteValuegeneric_OpPopCount8(v)
        case OpPtrIndex:
                return rewriteValuegeneric_OpPtrIndex(v)
        case OpRotateLeft16:
@@ -24771,6 +24779,150 @@ func rewriteValuegeneric_OpPhi(v *Value) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpPopCount16(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       config := b.Func.Config
+       // match: (PopCount16 (Const16 [c]))
+       // cond: config.PtrSize == 8
+       // result: (Const64 [int64(bits.OnesCount16(uint16(c)))])
+       for {
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               c := auxIntToInt16(v_0.AuxInt)
+               if !(config.PtrSize == 8) {
+                       break
+               }
+               v.reset(OpConst64)
+               v.AuxInt = int64ToAuxInt(int64(bits.OnesCount16(uint16(c))))
+               return true
+       }
+       // match: (PopCount16 (Const16 [c]))
+       // cond: config.PtrSize == 4
+       // result: (Const32 [int32(bits.OnesCount16(uint16(c)))])
+       for {
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               c := auxIntToInt16(v_0.AuxInt)
+               if !(config.PtrSize == 4) {
+                       break
+               }
+               v.reset(OpConst32)
+               v.AuxInt = int32ToAuxInt(int32(bits.OnesCount16(uint16(c))))
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpPopCount32(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       config := b.Func.Config
+       // match: (PopCount32 (Const32 [c]))
+       // cond: config.PtrSize == 8
+       // result: (Const64 [int64(bits.OnesCount32(uint32(c)))])
+       for {
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               c := auxIntToInt32(v_0.AuxInt)
+               if !(config.PtrSize == 8) {
+                       break
+               }
+               v.reset(OpConst64)
+               v.AuxInt = int64ToAuxInt(int64(bits.OnesCount32(uint32(c))))
+               return true
+       }
+       // match: (PopCount32 (Const32 [c]))
+       // cond: config.PtrSize == 4
+       // result: (Const32 [int32(bits.OnesCount32(uint32(c)))])
+       for {
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               c := auxIntToInt32(v_0.AuxInt)
+               if !(config.PtrSize == 4) {
+                       break
+               }
+               v.reset(OpConst32)
+               v.AuxInt = int32ToAuxInt(int32(bits.OnesCount32(uint32(c))))
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpPopCount64(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       config := b.Func.Config
+       // match: (PopCount64 (Const64 [c]))
+       // cond: config.PtrSize == 8
+       // result: (Const64 [int64(bits.OnesCount64(uint64(c)))])
+       for {
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               c := auxIntToInt64(v_0.AuxInt)
+               if !(config.PtrSize == 8) {
+                       break
+               }
+               v.reset(OpConst64)
+               v.AuxInt = int64ToAuxInt(int64(bits.OnesCount64(uint64(c))))
+               return true
+       }
+       // match: (PopCount64 (Const64 [c]))
+       // cond: config.PtrSize == 4
+       // result: (Const32 [int32(bits.OnesCount64(uint64(c)))])
+       for {
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               c := auxIntToInt64(v_0.AuxInt)
+               if !(config.PtrSize == 4) {
+                       break
+               }
+               v.reset(OpConst32)
+               v.AuxInt = int32ToAuxInt(int32(bits.OnesCount64(uint64(c))))
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpPopCount8(v *Value) bool {
+       v_0 := v.Args[0]
+       b := v.Block
+       config := b.Func.Config
+       // match: (PopCount8 (Const8 [c]))
+       // cond: config.PtrSize == 8
+       // result: (Const64 [int64(bits.OnesCount8(uint8(c)))])
+       for {
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               c := auxIntToInt8(v_0.AuxInt)
+               if !(config.PtrSize == 8) {
+                       break
+               }
+               v.reset(OpConst64)
+               v.AuxInt = int64ToAuxInt(int64(bits.OnesCount8(uint8(c))))
+               return true
+       }
+       // match: (PopCount8 (Const8 [c]))
+       // cond: config.PtrSize == 4
+       // result: (Const32 [int32(bits.OnesCount8(uint8(c)))])
+       for {
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               c := auxIntToInt8(v_0.AuxInt)
+               if !(config.PtrSize == 4) {
+                       break
+               }
+               v.reset(OpConst32)
+               v.AuxInt = int32ToAuxInt(int32(bits.OnesCount8(uint8(c))))
+               return true
+       }
+       return false
+}
 func rewriteValuegeneric_OpPtrIndex(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]