From: Jorropo Date: Sun, 9 Mar 2025 09:21:06 +0000 (+0100) Subject: cmd/compile: add constant folding for PopCount X-Git-Tag: go1.25rc1~763 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=3e033b7553e8d4893c931832ce25dd11fa22f254;p=gostls13.git cmd/compile: add constant folding for PopCount Change-Id: I6ea3f75ddd5c7af114ef77bc48f28c7f8570997b Reviewed-on: https://go-review.googlesource.com/c/go/+/656156 Reviewed-by: Keith Randall Reviewed-by: David Chase Auto-Submit: Jorropo LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall --- diff --git a/src/cmd/compile/internal/ssa/_gen/generic.rules b/src/cmd/compile/internal/ssa/_gen/generic.rules index 8a54645fee..49696cea2a 100644 --- a/src/cmd/compile/internal/ssa/_gen/generic.rules +++ b/src/cmd/compile/internal/ssa/_gen/generic.rules @@ -66,6 +66,14 @@ (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 diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index 0cdaded87f..b951ecdfc5 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -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]