aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile
diff options
context:
space:
mode:
authorJorropo <jorropo.pgm@gmail.com>2026-03-29 05:19:58 +0200
committerGopher Robot <gobot@golang.org>2026-04-03 13:21:37 -0700
commit0a36b58888cc41b276362673f70be87efd7e55ad (patch)
tree4e23a040eca0b800599113ffdd20d9c5f641c637 /src/cmd/compile
parent142f2376017887a3ed02dc1bc91542d39cfe2ecd (diff)
downloadgo-0a36b58888cc41b276362673f70be87efd7e55ad.tar.xz
cmd/compile: extend all the cmov into math generic rules with their contrary
If the bool comes from a local operation this is foldable into the comparison. if a == b { } else { x++ } becomes: x += !(a == b) becomes: x += a != b If the bool is passed in or loaded rather than being locally computed this adds an extra XOR ^1 to invert it. But at worst it should make the math equal to the compute + CMP + CMOV which is a tie on modern CPUs which can execute CMOV on all int ALUs and a win on the cheaper or older ones which can't. Change-Id: Idd2566c7a3826ec432ebfbba7b3898aa0db4b812 Reviewed-on: https://go-review.googlesource.com/c/go/+/760922 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Auto-Submit: Jorropo <jorropo.pgm@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Junyang Shao <shaojunyang@google.com>
Diffstat (limited to 'src/cmd/compile')
-rw-r--r--src/cmd/compile/internal/ssa/_gen/generic.rules17
-rw-r--r--src/cmd/compile/internal/ssa/rewritegeneric.go756
2 files changed, 773 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/generic.rules b/src/cmd/compile/internal/ssa/_gen/generic.rules
index 7dcf818976..e75f371790 100644
--- a/src/cmd/compile/internal/ssa/_gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/_gen/generic.rules
@@ -2300,25 +2300,42 @@
// if b { x++ } => x += b // but not on arm64 because it has CSINC
(CondSelect (Add8 <t> x (Const8 [1])) x bool) && config.arch != "arm64" => (Add8 x (CvtBoolToUint8 <t> bool))
(CondSelect (Add(64|32|16) <t> x (Const(64|32|16) [1])) x bool) && config.arch != "arm64" => (Add(64|32|16) x (ZeroExt8to(64|32|16) <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> bool)))
+// if !b { x++ } => x += !b // but not on arm64 because it has CSINC
+(CondSelect x (Add8 <t> x (Const8 [1])) bool) && config.arch != "arm64" => (Add8 x (CvtBoolToUint8 <t> (Not <bool.Type> bool)))
+(CondSelect x (Add(64|32|16) <t> x (Const(64|32|16) [1])) bool) && config.arch != "arm64" => (Add(64|32|16) x (ZeroExt8to(64|32|16) <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
// if b { x-- } => x -= b
(CondSelect (Add8 <t> x (Const8 [-1])) x bool) => (Sub8 x (CvtBoolToUint8 <t> bool))
(CondSelect (Add(64|32|16) <t> x (Const(64|32|16) [-1])) x bool) => (Sub(64|32|16) x (ZeroExt8to(64|32|16) <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> bool)))
+// if !b { x-- } => x -= !b
+(CondSelect x (Add8 <t> x (Const8 [-1])) bool) => (Sub8 x (CvtBoolToUint8 <t> (Not <bool.Type> bool)))
+(CondSelect x (Add(64|32|16) <t> x (Const(64|32|16) [-1])) bool) => (Sub(64|32|16) x (ZeroExt8to(64|32|16) <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
// if b { x <<= 1 } => x <<= b
(CondSelect (Lsh(64|32|16|8)x64 x (Const64 [1])) x bool) => (Lsh(64|32|16|8)x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> bool))
+// if !b { x <<= 1 } => x <<= !b
+(CondSelect x (Lsh(64|32|16|8)x64 x (Const64 [1])) bool) => (Lsh(64|32|16|8)x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
// if b { x >>= 1 } => x >>= b
(CondSelect (Rsh(64|32|16|8)x64 x (Const64 [1])) x bool) => (Rsh(64|32|16|8)x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> bool))
(CondSelect (Rsh(64|32|16|8)Ux64 x (Const64 [1])) x bool) => (Rsh(64|32|16|8)Ux8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> bool))
+// if !b { x >>= 1 } => x >>= !b
+(CondSelect x (Rsh(64|32|16|8)x64 x (Const64 [1])) bool) => (Rsh(64|32|16|8)x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+(CondSelect x (Rsh(64|32|16|8)Ux64 x (Const64 [1])) bool) => (Rsh(64|32|16|8)Ux8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
// if b { x |= 1 } => x |= b
(CondSelect (Or8 <t> x (Const8 [1])) x bool) => (Or8 x (CvtBoolToUint8 <t> bool))
(CondSelect (Or(64|32|16) <t> x (Const(64|32|16) [1])) x bool) => (Or(64|32|16) x (ZeroExt8to(64|32|16) <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> bool)))
+// if !b { x |= 1 } => x |= !b
+(CondSelect x (Or8 <t> x (Const8 [1])) bool) => (Or8 x (CvtBoolToUint8 <t> (Not <bool.Type> bool)))
+(CondSelect x (Or(64|32|16) <t> x (Const(64|32|16) [1])) bool) => (Or(64|32|16) x (ZeroExt8to(64|32|16) <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
// if b { x ^= 1 } => x ^= b
(CondSelect (Xor8 <t> x (Const8 [1])) x bool) => (Xor8 x (CvtBoolToUint8 <t> bool))
(CondSelect (Xor(64|32|16) <t> x (Const(64|32|16) [1])) x bool) => (Xor(64|32|16) x (ZeroExt8to(64|32|16) <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> bool)))
+// if !b { x ^= 1 } => x ^= !b
+(CondSelect x (Xor8 <t> x (Const8 [1])) bool) => (Xor8 x (CvtBoolToUint8 <t> (Not <bool.Type> bool)))
+(CondSelect x (Xor(64|32|16) <t> x (Const(64|32|16) [1])) bool) => (Xor(64|32|16) x (ZeroExt8to(64|32|16) <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
// bool(int(x)) => x
(Neq8 (CvtBoolToUint8 x) (Const8 [0])) => x
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index 263302c7e7..0386763639 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -6030,6 +6030,132 @@ func rewriteValuegeneric_OpCondSelect(v *Value) bool {
}
break
}
+ // match: (CondSelect x (Add8 <t> x (Const8 [1])) bool)
+ // cond: config.arch != "arm64"
+ // result: (Add8 x (CvtBoolToUint8 <t> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpAdd8 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst8 || auxIntToInt8(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ if !(config.arch != "arm64") {
+ continue
+ }
+ v.reset(OpAdd8)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, t)
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Add64 <t> x (Const64 [1])) bool)
+ // cond: config.arch != "arm64"
+ // result: (Add64 x (ZeroExt8to64 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpAdd64 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ if !(config.arch != "arm64") {
+ continue
+ }
+ v.reset(OpAdd64)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Add32 <t> x (Const32 [1])) bool)
+ // cond: config.arch != "arm64"
+ // result: (Add32 x (ZeroExt8to32 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpAdd32 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst32 || auxIntToInt32(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ if !(config.arch != "arm64") {
+ continue
+ }
+ v.reset(OpAdd32)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to32, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Add16 <t> x (Const16 [1])) bool)
+ // cond: config.arch != "arm64"
+ // result: (Add16 x (ZeroExt8to16 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpAdd16 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst16 || auxIntToInt16(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ if !(config.arch != "arm64") {
+ continue
+ }
+ v.reset(OpAdd16)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to16, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
// match: (CondSelect (Add8 <t> x (Const8 [-1])) x bool)
// result: (Sub8 x (CvtBoolToUint8 <t> bool))
for {
@@ -6132,6 +6258,116 @@ func rewriteValuegeneric_OpCondSelect(v *Value) bool {
}
break
}
+ // match: (CondSelect x (Add8 <t> x (Const8 [-1])) bool)
+ // result: (Sub8 x (CvtBoolToUint8 <t> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpAdd8 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst8 || auxIntToInt8(v_1_1.AuxInt) != -1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpSub8)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, t)
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Add64 <t> x (Const64 [-1])) bool)
+ // result: (Sub64 x (ZeroExt8to64 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpAdd64 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != -1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpSub64)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Add32 <t> x (Const32 [-1])) bool)
+ // result: (Sub32 x (ZeroExt8to32 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpAdd32 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst32 || auxIntToInt32(v_1_1.AuxInt) != -1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpSub32)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to32, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Add16 <t> x (Const16 [-1])) bool)
+ // result: (Sub16 x (ZeroExt8to16 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpAdd16 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst16 || auxIntToInt16(v_1_1.AuxInt) != -1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpSub16)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to16, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
// match: (CondSelect (Lsh64x64 x (Const64 [1])) x bool)
// result: (Lsh64x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> bool))
for {
@@ -6212,6 +6448,106 @@ func rewriteValuegeneric_OpCondSelect(v *Value) bool {
v.AddArg2(x, v0)
return true
}
+ // match: (CondSelect x (Lsh64x64 x (Const64 [1])) bool)
+ // result: (Lsh64x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpLsh64x64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpLsh64x8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ // match: (CondSelect x (Lsh32x64 x (Const64 [1])) bool)
+ // result: (Lsh32x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpLsh32x64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpLsh32x8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ // match: (CondSelect x (Lsh16x64 x (Const64 [1])) bool)
+ // result: (Lsh16x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpLsh16x64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpLsh16x8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ // match: (CondSelect x (Lsh8x64 x (Const64 [1])) bool)
+ // result: (Lsh8x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpLsh8x64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpLsh8x8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
// match: (CondSelect (Rsh64x64 x (Const64 [1])) x bool)
// result: (Rsh64x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> bool))
for {
@@ -6372,6 +6708,206 @@ func rewriteValuegeneric_OpCondSelect(v *Value) bool {
v.AddArg2(x, v0)
return true
}
+ // match: (CondSelect x (Rsh64x64 x (Const64 [1])) bool)
+ // result: (Rsh64x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpRsh64x64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpRsh64x8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ // match: (CondSelect x (Rsh32x64 x (Const64 [1])) bool)
+ // result: (Rsh32x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpRsh32x64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpRsh32x8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ // match: (CondSelect x (Rsh16x64 x (Const64 [1])) bool)
+ // result: (Rsh16x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpRsh16x64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpRsh16x8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ // match: (CondSelect x (Rsh8x64 x (Const64 [1])) bool)
+ // result: (Rsh8x8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpRsh8x64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpRsh8x8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ // match: (CondSelect x (Rsh64Ux64 x (Const64 [1])) bool)
+ // result: (Rsh64Ux8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpRsh64Ux64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpRsh64Ux8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ // match: (CondSelect x (Rsh32Ux64 x (Const64 [1])) bool)
+ // result: (Rsh32Ux8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpRsh32Ux64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpRsh32Ux8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ // match: (CondSelect x (Rsh16Ux64 x (Const64 [1])) bool)
+ // result: (Rsh16Ux8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpRsh16Ux64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpRsh16Ux8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ // match: (CondSelect x (Rsh8Ux64 x (Const64 [1])) bool)
+ // result: (Rsh8Ux8 [true] x (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpRsh8Ux64 {
+ break
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ break
+ }
+ bool := v_2
+ v.reset(OpRsh8Ux8)
+ v.AuxInt = boolToAuxInt(true)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
// match: (CondSelect (Or8 <t> x (Const8 [1])) x bool)
// result: (Or8 x (CvtBoolToUint8 <t> bool))
for {
@@ -6474,6 +7010,116 @@ func rewriteValuegeneric_OpCondSelect(v *Value) bool {
}
break
}
+ // match: (CondSelect x (Or8 <t> x (Const8 [1])) bool)
+ // result: (Or8 x (CvtBoolToUint8 <t> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpOr8 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst8 || auxIntToInt8(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpOr8)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, t)
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Or64 <t> x (Const64 [1])) bool)
+ // result: (Or64 x (ZeroExt8to64 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpOr64 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpOr64)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Or32 <t> x (Const32 [1])) bool)
+ // result: (Or32 x (ZeroExt8to32 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpOr32 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst32 || auxIntToInt32(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpOr32)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to32, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Or16 <t> x (Const16 [1])) bool)
+ // result: (Or16 x (ZeroExt8to16 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpOr16 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst16 || auxIntToInt16(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpOr16)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to16, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
// match: (CondSelect (Xor8 <t> x (Const8 [1])) x bool)
// result: (Xor8 x (CvtBoolToUint8 <t> bool))
for {
@@ -6576,6 +7222,116 @@ func rewriteValuegeneric_OpCondSelect(v *Value) bool {
}
break
}
+ // match: (CondSelect x (Xor8 <t> x (Const8 [1])) bool)
+ // result: (Xor8 x (CvtBoolToUint8 <t> (Not <bool.Type> bool)))
+ for {
+ x := v_0
+ if v_1.Op != OpXor8 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst8 || auxIntToInt8(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpXor8)
+ v0 := b.NewValue0(v.Pos, OpCvtBoolToUint8, t)
+ v1 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v1.AddArg(bool)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Xor64 <t> x (Const64 [1])) bool)
+ // result: (Xor64 x (ZeroExt8to64 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpXor64 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst64 || auxIntToInt64(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpXor64)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Xor32 <t> x (Const32 [1])) bool)
+ // result: (Xor32 x (ZeroExt8to32 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpXor32 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst32 || auxIntToInt32(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpXor32)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to32, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
+ // match: (CondSelect x (Xor16 <t> x (Const16 [1])) bool)
+ // result: (Xor16 x (ZeroExt8to16 <t> (CvtBoolToUint8 <types.Types[types.TUINT8]> (Not <bool.Type> bool))))
+ for {
+ x := v_0
+ if v_1.Op != OpXor16 {
+ break
+ }
+ t := v_1.Type
+ _ = v_1.Args[1]
+ v_1_0 := v_1.Args[0]
+ v_1_1 := v_1.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+ if x != v_1_0 || v_1_1.Op != OpConst16 || auxIntToInt16(v_1_1.AuxInt) != 1 {
+ continue
+ }
+ bool := v_2
+ v.reset(OpXor16)
+ v0 := b.NewValue0(v.Pos, OpZeroExt8to16, t)
+ v1 := b.NewValue0(v.Pos, OpCvtBoolToUint8, types.Types[types.TUINT8])
+ v2 := b.NewValue0(v.Pos, OpNot, bool.Type)
+ v2.AddArg(bool)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
return false
}
func rewriteValuegeneric_OpConstInterface(v *Value) bool {