]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimize bitset tests
authorLE Manh Cuong <cuong.manhle.vn@gmail.com>
Wed, 8 May 2019 10:02:23 +0000 (17:02 +0700)
committerDaniel Martí <mvdan@mvdan.cc>
Tue, 27 Aug 2019 18:01:16 +0000 (18:01 +0000)
The assembly output for x & c == c, where c is power of 2:

MOVQ "".set+8(SP), AX
ANDQ $8, AX
CMPQ AX, $8
SETEQ "".~r2+24(SP)

With optimization using bitset:

MOVQ "".set+8(SP), AX
BTL $3, AX
SETCS "".~r2+24(SP)

output less than 1 instruction.

However, there is no speed improvement:

name         old time/op  new time/op  delta
AllBitSet-8  0.35ns ± 0%  0.35ns ± 0%   ~     (all equal)

Fixes #31904

Change-Id: I5dca4e410bf45716ed2145e3473979ec997e35d4
Reviewed-on: https://go-review.googlesource.com/c/go/+/175957
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go
test/codegen/bits.go

index 454eb498c6c37b66cfde101f56979935638c06e4..347bf2a00f771c479fa055913954e2f2cd2238df 100644 (file)
 (Eq(8|16|32|64)  s:(Sub(8|16|32|64) x y) (Const(8|16|32|64) [0])) && s.Uses == 1 -> (Eq(8|16|32|64)  x y)
 (Neq(8|16|32|64) s:(Sub(8|16|32|64) x y) (Const(8|16|32|64) [0])) && s.Uses == 1 -> (Neq(8|16|32|64) x y)
 
+// Optimize bitsets
+(Eq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [y])) && isPowerOfTwo(y)
+  -> (Neq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [0]))
+(Neq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [y])) && isPowerOfTwo(y)
+  -> (Eq(8|16|32|64) (And(8|16|32|64) <t> x (Const(8|16|32|64) <t> [y])) (Const(8|16|32|64) <t> [0]))
+
 // Reassociate expressions involving
 // constants such that constants come first,
 // exposing obvious constant-folding opportunities.
index db0b1749a89c0d482fd2a9fed90b6ffb261054b1..6b0cd050478d6cab0e5b6abcaf2b92626fbb663e 100644 (file)
@@ -89,7 +89,7 @@ func rewriteValuegeneric(v *Value) bool {
        case OpDiv8u:
                return rewriteValuegeneric_OpDiv8u_0(v)
        case OpEq16:
-               return rewriteValuegeneric_OpEq16_0(v) || rewriteValuegeneric_OpEq16_10(v) || rewriteValuegeneric_OpEq16_20(v) || rewriteValuegeneric_OpEq16_30(v) || rewriteValuegeneric_OpEq16_40(v) || rewriteValuegeneric_OpEq16_50(v)
+               return rewriteValuegeneric_OpEq16_0(v) || rewriteValuegeneric_OpEq16_10(v) || rewriteValuegeneric_OpEq16_20(v) || rewriteValuegeneric_OpEq16_30(v) || rewriteValuegeneric_OpEq16_40(v) || rewriteValuegeneric_OpEq16_50(v) || rewriteValuegeneric_OpEq16_60(v)
        case OpEq32:
                return rewriteValuegeneric_OpEq32_0(v) || rewriteValuegeneric_OpEq32_10(v) || rewriteValuegeneric_OpEq32_20(v) || rewriteValuegeneric_OpEq32_30(v) || rewriteValuegeneric_OpEq32_40(v) || rewriteValuegeneric_OpEq32_50(v) || rewriteValuegeneric_OpEq32_60(v) || rewriteValuegeneric_OpEq32_70(v) || rewriteValuegeneric_OpEq32_80(v) || rewriteValuegeneric_OpEq32_90(v)
        case OpEq32F:
@@ -275,17 +275,17 @@ func rewriteValuegeneric(v *Value) bool {
        case OpNeg8:
                return rewriteValuegeneric_OpNeg8_0(v)
        case OpNeq16:
-               return rewriteValuegeneric_OpNeq16_0(v)
+               return rewriteValuegeneric_OpNeq16_0(v) || rewriteValuegeneric_OpNeq16_10(v)
        case OpNeq32:
-               return rewriteValuegeneric_OpNeq32_0(v)
+               return rewriteValuegeneric_OpNeq32_0(v) || rewriteValuegeneric_OpNeq32_10(v)
        case OpNeq32F:
                return rewriteValuegeneric_OpNeq32F_0(v)
        case OpNeq64:
-               return rewriteValuegeneric_OpNeq64_0(v)
+               return rewriteValuegeneric_OpNeq64_0(v) || rewriteValuegeneric_OpNeq64_10(v)
        case OpNeq64F:
                return rewriteValuegeneric_OpNeq64F_0(v)
        case OpNeq8:
-               return rewriteValuegeneric_OpNeq8_0(v)
+               return rewriteValuegeneric_OpNeq8_0(v) || rewriteValuegeneric_OpNeq8_10(v)
        case OpNeqB:
                return rewriteValuegeneric_OpNeqB_0(v)
        case OpNeqInter:
@@ -12716,6 +12716,188 @@ func rewriteValuegeneric_OpEq16_50(v *Value) bool {
                v.AddArg(y)
                return true
        }
+       // match: (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd16 {
+                       break
+               }
+               t := v_0.Type
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpConst16 {
+                       break
+               }
+               if v_0_1.Type != t {
+                       break
+               }
+               y := v_0_1.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst16 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq16)
+               v0 := b.NewValue0(v.Pos, OpAnd16, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst16, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst16, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Eq16 (And16 <t> (Const16 <t> [y]) x) (Const16 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd16 {
+                       break
+               }
+               t := v_0.Type
+               x := v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpConst16 {
+                       break
+               }
+               if v_0_0.Type != t {
+                       break
+               }
+               y := v_0_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst16 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq16)
+               v0 := b.NewValue0(v.Pos, OpAnd16, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst16, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst16, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Eq16 (Const16 <t> [y]) (And16 <t> x (Const16 <t> [y])))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd16 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               _ = v_1.Args[1]
+               x := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpConst16 {
+                       break
+               }
+               if v_1_1.Type != t {
+                       break
+               }
+               if v_1_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq16)
+               v0 := b.NewValue0(v.Pos, OpAnd16, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst16, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst16, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpEq16_60(v *Value) bool {
+       b := v.Block
+       // match: (Eq16 (Const16 <t> [y]) (And16 <t> (Const16 <t> [y]) x))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd16 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               x := v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst16 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               if v_1_0.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq16)
+               v0 := b.NewValue0(v.Pos, OpAnd16, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst16, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst16, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpEq32_0(v *Value) bool {
@@ -19708,6 +19890,184 @@ func rewriteValuegeneric_OpEq32_90(v *Value) bool {
                v.AddArg(y)
                return true
        }
+       // match: (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd32 {
+                       break
+               }
+               t := v_0.Type
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpConst32 {
+                       break
+               }
+               if v_0_1.Type != t {
+                       break
+               }
+               y := v_0_1.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst32 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq32)
+               v0 := b.NewValue0(v.Pos, OpAnd32, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst32, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst32, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Eq32 (And32 <t> (Const32 <t> [y]) x) (Const32 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd32 {
+                       break
+               }
+               t := v_0.Type
+               x := v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpConst32 {
+                       break
+               }
+               if v_0_0.Type != t {
+                       break
+               }
+               y := v_0_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst32 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq32)
+               v0 := b.NewValue0(v.Pos, OpAnd32, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst32, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst32, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Eq32 (Const32 <t> [y]) (And32 <t> x (Const32 <t> [y])))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd32 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               _ = v_1.Args[1]
+               x := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpConst32 {
+                       break
+               }
+               if v_1_1.Type != t {
+                       break
+               }
+               if v_1_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq32)
+               v0 := b.NewValue0(v.Pos, OpAnd32, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst32, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst32, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Eq32 (Const32 <t> [y]) (And32 <t> (Const32 <t> [y]) x))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd32 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               x := v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst32 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               if v_1_0.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq32)
+               v0 := b.NewValue0(v.Pos, OpAnd32, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst32, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst32, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpEq32F_0(v *Value) bool {
@@ -24058,6 +24418,7 @@ func rewriteValuegeneric_OpEq64_50(v *Value) bool {
        return false
 }
 func rewriteValuegeneric_OpEq64_60(v *Value) bool {
+       b := v.Block
        // match: (Eq64 (Const64 [0]) s:(Sub64 x y))
        // cond: s.Uses == 1
        // result: (Eq64 x y)
@@ -24084,6 +24445,184 @@ func rewriteValuegeneric_OpEq64_60(v *Value) bool {
                v.AddArg(y)
                return true
        }
+       // match: (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd64 {
+                       break
+               }
+               t := v_0.Type
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpConst64 {
+                       break
+               }
+               if v_0_1.Type != t {
+                       break
+               }
+               y := v_0_1.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq64)
+               v0 := b.NewValue0(v.Pos, OpAnd64, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst64, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst64, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Eq64 (And64 <t> (Const64 <t> [y]) x) (Const64 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd64 {
+                       break
+               }
+               t := v_0.Type
+               x := v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpConst64 {
+                       break
+               }
+               if v_0_0.Type != t {
+                       break
+               }
+               y := v_0_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq64)
+               v0 := b.NewValue0(v.Pos, OpAnd64, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst64, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst64, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Eq64 (Const64 <t> [y]) (And64 <t> x (Const64 <t> [y])))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd64 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               _ = v_1.Args[1]
+               x := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpConst64 {
+                       break
+               }
+               if v_1_1.Type != t {
+                       break
+               }
+               if v_1_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq64)
+               v0 := b.NewValue0(v.Pos, OpAnd64, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst64, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst64, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Eq64 (Const64 <t> [y]) (And64 <t> (Const64 <t> [y]) x))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd64 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               x := v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst64 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               if v_1_0.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq64)
+               v0 := b.NewValue0(v.Pos, OpAnd64, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst64, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst64, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpEq64F_0(v *Value) bool {
@@ -26177,6 +26716,184 @@ func rewriteValuegeneric_OpEq8_30(v *Value) bool {
                v.AddArg(y)
                return true
        }
+       // match: (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd8 {
+                       break
+               }
+               t := v_0.Type
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpConst8 {
+                       break
+               }
+               if v_0_1.Type != t {
+                       break
+               }
+               y := v_0_1.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst8 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq8)
+               v0 := b.NewValue0(v.Pos, OpAnd8, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst8, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst8, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Eq8 (And8 <t> (Const8 <t> [y]) x) (Const8 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd8 {
+                       break
+               }
+               t := v_0.Type
+               x := v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpConst8 {
+                       break
+               }
+               if v_0_0.Type != t {
+                       break
+               }
+               y := v_0_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst8 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq8)
+               v0 := b.NewValue0(v.Pos, OpAnd8, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst8, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst8, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Eq8 (Const8 <t> [y]) (And8 <t> x (Const8 <t> [y])))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd8 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               _ = v_1.Args[1]
+               x := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpConst8 {
+                       break
+               }
+               if v_1_1.Type != t {
+                       break
+               }
+               if v_1_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq8)
+               v0 := b.NewValue0(v.Pos, OpAnd8, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst8, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst8, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Eq8 (Const8 <t> [y]) (And8 <t> (Const8 <t> [y]) x))
+       // cond: isPowerOfTwo(y)
+       // result: (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd8 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               x := v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst8 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               if v_1_0.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpNeq8)
+               v0 := b.NewValue0(v.Pos, OpAnd8, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst8, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst8, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpEqB_0(v *Value) bool {
@@ -35976,6 +36693,188 @@ func rewriteValuegeneric_OpNeq16_0(v *Value) bool {
                v.AddArg(y)
                return true
        }
+       // match: (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd16 {
+                       break
+               }
+               t := v_0.Type
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpConst16 {
+                       break
+               }
+               if v_0_1.Type != t {
+                       break
+               }
+               y := v_0_1.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst16 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq16)
+               v0 := b.NewValue0(v.Pos, OpAnd16, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst16, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst16, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpNeq16_10(v *Value) bool {
+       b := v.Block
+       // match: (Neq16 (And16 <t> (Const16 <t> [y]) x) (Const16 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd16 {
+                       break
+               }
+               t := v_0.Type
+               x := v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpConst16 {
+                       break
+               }
+               if v_0_0.Type != t {
+                       break
+               }
+               y := v_0_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst16 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq16)
+               v0 := b.NewValue0(v.Pos, OpAnd16, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst16, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst16, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Neq16 (Const16 <t> [y]) (And16 <t> x (Const16 <t> [y])))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd16 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               _ = v_1.Args[1]
+               x := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpConst16 {
+                       break
+               }
+               if v_1_1.Type != t {
+                       break
+               }
+               if v_1_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq16)
+               v0 := b.NewValue0(v.Pos, OpAnd16, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst16, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst16, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Neq16 (Const16 <t> [y]) (And16 <t> (Const16 <t> [y]) x))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd16 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               x := v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst16 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               if v_1_0.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq16)
+               v0 := b.NewValue0(v.Pos, OpAnd16, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst16, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst16, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpNeq32_0(v *Value) bool {
@@ -36208,6 +37107,188 @@ func rewriteValuegeneric_OpNeq32_0(v *Value) bool {
                v.AddArg(y)
                return true
        }
+       // match: (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd32 {
+                       break
+               }
+               t := v_0.Type
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpConst32 {
+                       break
+               }
+               if v_0_1.Type != t {
+                       break
+               }
+               y := v_0_1.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst32 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq32)
+               v0 := b.NewValue0(v.Pos, OpAnd32, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst32, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst32, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpNeq32_10(v *Value) bool {
+       b := v.Block
+       // match: (Neq32 (And32 <t> (Const32 <t> [y]) x) (Const32 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd32 {
+                       break
+               }
+               t := v_0.Type
+               x := v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpConst32 {
+                       break
+               }
+               if v_0_0.Type != t {
+                       break
+               }
+               y := v_0_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst32 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq32)
+               v0 := b.NewValue0(v.Pos, OpAnd32, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst32, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst32, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Neq32 (Const32 <t> [y]) (And32 <t> x (Const32 <t> [y])))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd32 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               _ = v_1.Args[1]
+               x := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpConst32 {
+                       break
+               }
+               if v_1_1.Type != t {
+                       break
+               }
+               if v_1_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq32)
+               v0 := b.NewValue0(v.Pos, OpAnd32, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst32, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst32, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Neq32 (Const32 <t> [y]) (And32 <t> (Const32 <t> [y]) x))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd32 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               x := v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst32 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               if v_1_0.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq32)
+               v0 := b.NewValue0(v.Pos, OpAnd32, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst32, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst32, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpNeq32F_0(v *Value) bool {
@@ -36481,6 +37562,188 @@ func rewriteValuegeneric_OpNeq64_0(v *Value) bool {
                v.AddArg(y)
                return true
        }
+       // match: (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd64 {
+                       break
+               }
+               t := v_0.Type
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpConst64 {
+                       break
+               }
+               if v_0_1.Type != t {
+                       break
+               }
+               y := v_0_1.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq64)
+               v0 := b.NewValue0(v.Pos, OpAnd64, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst64, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst64, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpNeq64_10(v *Value) bool {
+       b := v.Block
+       // match: (Neq64 (And64 <t> (Const64 <t> [y]) x) (Const64 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd64 {
+                       break
+               }
+               t := v_0.Type
+               x := v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpConst64 {
+                       break
+               }
+               if v_0_0.Type != t {
+                       break
+               }
+               y := v_0_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq64)
+               v0 := b.NewValue0(v.Pos, OpAnd64, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst64, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst64, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Neq64 (Const64 <t> [y]) (And64 <t> x (Const64 <t> [y])))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd64 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               _ = v_1.Args[1]
+               x := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpConst64 {
+                       break
+               }
+               if v_1_1.Type != t {
+                       break
+               }
+               if v_1_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq64)
+               v0 := b.NewValue0(v.Pos, OpAnd64, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst64, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst64, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Neq64 (Const64 <t> [y]) (And64 <t> (Const64 <t> [y]) x))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd64 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               x := v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst64 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               if v_1_0.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq64)
+               v0 := b.NewValue0(v.Pos, OpAnd64, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst64, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst64, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpNeq64F_0(v *Value) bool {
@@ -36754,6 +38017,188 @@ func rewriteValuegeneric_OpNeq8_0(v *Value) bool {
                v.AddArg(y)
                return true
        }
+       // match: (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd8 {
+                       break
+               }
+               t := v_0.Type
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpConst8 {
+                       break
+               }
+               if v_0_1.Type != t {
+                       break
+               }
+               y := v_0_1.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst8 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq8)
+               v0 := b.NewValue0(v.Pos, OpAnd8, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst8, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst8, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpNeq8_10(v *Value) bool {
+       b := v.Block
+       // match: (Neq8 (And8 <t> (Const8 <t> [y]) x) (Const8 <t> [y]))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd8 {
+                       break
+               }
+               t := v_0.Type
+               x := v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpConst8 {
+                       break
+               }
+               if v_0_0.Type != t {
+                       break
+               }
+               y := v_0_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst8 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               if v_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq8)
+               v0 := b.NewValue0(v.Pos, OpAnd8, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst8, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst8, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Neq8 (Const8 <t> [y]) (And8 <t> x (Const8 <t> [y])))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd8 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               _ = v_1.Args[1]
+               x := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpConst8 {
+                       break
+               }
+               if v_1_1.Type != t {
+                       break
+               }
+               if v_1_1.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq8)
+               v0 := b.NewValue0(v.Pos, OpAnd8, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst8, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst8, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
+       // match: (Neq8 (Const8 <t> [y]) (And8 <t> (Const8 <t> [y]) x))
+       // cond: isPowerOfTwo(y)
+       // result: (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               t := v_0.Type
+               y := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd8 {
+                       break
+               }
+               if v_1.Type != t {
+                       break
+               }
+               x := v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst8 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               if v_1_0.AuxInt != y {
+                       break
+               }
+               if !(isPowerOfTwo(y)) {
+                       break
+               }
+               v.reset(OpEq8)
+               v0 := b.NewValue0(v.Pos, OpAnd8, t)
+               v0.AddArg(x)
+               v1 := b.NewValue0(v.Pos, OpConst8, t)
+               v1.AuxInt = y
+               v0.AddArg(v1)
+               v.AddArg(v0)
+               v2 := b.NewValue0(v.Pos, OpConst8, t)
+               v2.AuxInt = 0
+               v.AddArg(v2)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpNeqB_0(v *Value) bool {
index 65d57c8f9f07887f80d0d763578f3bb94431c117..18f9daf7cf394274f3c1a3f65a3e5ec161dcd091 100644 (file)
@@ -314,3 +314,15 @@ func op_orn(x, y uint32) uint32 {
        // arm64:`ORN\t`,-`ORR`
        return x | ^y
 }
+
+// check bitsets
+func bitSetPowerOf2Test(x int) bool {
+       // amd64:"BTL\t[$]3"
+       return x&8 == 8
+}
+
+func bitSetTest(x int) bool {
+       // amd64:"ANDQ\t[$]9, AX"
+       // amd64:"CMPQ\tAX, [$]9"
+       return x&9 == 9
+}