]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile/ssa: more aggressive constant folding
authorphilhofer <phofer@umich.edu>
Mon, 20 Feb 2017 16:43:54 +0000 (08:43 -0800)
committerJosh Bleecher Snyder <josharian@gmail.com>
Tue, 28 Feb 2017 20:25:33 +0000 (20:25 +0000)
Add rewrite rules that canonicalize the location
of constants in expressions, and fold conststants
that appear in operations that can be trivially
reassociated.

After this change, the compiler constant-folds
expressions like "4 + x - 1" and "4 & x & 1"

Benchmarks affected on darwin/amd64:

name                     old time/op    new time/op    delta
FmtFprintfInt-8            82.1ns ± 1%    81.7ns ± 1%  -0.46%  (p=0.023 n=8+9)
FmtFprintfIntInt-8          122ns ± 2%     120ns ± 2%  -1.48%  (p=0.047 n=10+10)
FmtManyArgs-8               493ns ± 0%     486ns ± 1%  -1.37%  (p=0.000 n=8+10)
Gzip-8                      230ms ± 0%     229ms ± 1%  -0.46%  (p=0.001 n=10+9)
HTTPClientServer-8         74.5µs ± 1%    73.7µs ± 1%  -1.11%  (p=0.000 n=10+10)
JSONDecode-8               51.7ms ± 0%    51.9ms ± 1%  +0.42%  (p=0.017 n=10+9)
RegexpMatchEasy0_32-8      82.6ns ± 1%    81.7ns ± 0%  -1.02%  (p=0.000 n=9+8)
RegexpMatchMedium_32-8      121ns ± 1%     120ns ± 1%  -1.48%  (p=0.001 n=10+10)
Revcomp-8                   426ms ± 1%     400ms ± 1%  -6.16%  (p=0.000 n=10+10)
TimeFormat-8                330ns ± 1%     327ns ± 0%  -0.82%  (p=0.000 n=10+10)

name                     old speed      new speed      delta
Gzip-8                   84.4MB/s ± 0%  84.8MB/s ± 1%  +0.47%  (p=0.001 n=10+9)
JSONDecode-8             37.6MB/s ± 0%  37.4MB/s ± 1%  -0.42%  (p=0.016 n=10+9)
RegexpMatchEasy0_32-8     387MB/s ± 1%   392MB/s ± 0%  +1.06%  (p=0.000 n=9+8)
RegexpMatchMedium_32-8   8.21MB/s ± 1%  8.34MB/s ± 1%  +1.58%  (p=0.000 n=10+9)
Revcomp-8                 597MB/s ± 1%   636MB/s ± 1%  +6.57%  (p=0.000 n=10+10)

Change-Id: Ie37ff91605b76a984a8400dfd1e34f50bf61c864
Reviewed-on: https://go-review.googlesource.com/37290
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go
test/loopbce.go

index f485f43875265ed7f563e65b3afa9612ecec8fcb..740ba8606a0d99d4f9930aea2891f2bea35c2ce6 100644 (file)
         (Const32F [f2i(float64(i2f32(c) * i2f32(d)))])
 (Mul64F (Const64F [c]) (Const64F [d])) -> (Const64F [f2i(i2f(c) * i2f(d))])
 
+(And8   (Const8 [c])   (Const8 [d]))   -> (Const8  [int64(int8(c&d))])
+(And16  (Const16 [c])  (Const16 [d]))  -> (Const16 [int64(int16(c&d))])
+(And32  (Const32 [c])  (Const32 [d]))  -> (Const32 [int64(int32(c&d))])
+(And64  (Const64 [c])  (Const64 [d]))  -> (Const64 [c&d])
+
+(Or8   (Const8 [c])   (Const8 [d]))   -> (Const8  [int64(int8(c|d))])
+(Or16  (Const16 [c])  (Const16 [d]))  -> (Const16 [int64(int16(c|d))])
+(Or32  (Const32 [c])  (Const32 [d]))  -> (Const32 [int64(int32(c|d))])
+(Or64  (Const64 [c])  (Const64 [d]))  -> (Const64 [c|d])
+
+(Xor8   (Const8 [c])   (Const8 [d]))   -> (Const8  [int64(int8(c^d))])
+(Xor16  (Const16 [c])  (Const16 [d]))  -> (Const16 [int64(int16(c^d))])
+(Xor32  (Const32 [c])  (Const32 [d]))  -> (Const32 [int64(int32(c^d))])
+(Xor64  (Const64 [c])  (Const64 [d]))  -> (Const64 [c^d])
+
 (Div8   (Const8  [c])  (Const8  [d])) && d != 0 -> (Const8  [int64(int8(c)/int8(d))])
 (Div16  (Const16 [c])  (Const16 [d])) && d != 0 -> (Const16 [int64(int16(c)/int16(d))])
 (Div32  (Const32 [c])  (Const32 [d])) && d != 0 -> (Const32 [int64(int32(c)/int32(d))])
 (Neg16 (Sub16 x y)) -> (Sub16 y x)
 (Neg32 (Sub32 x y)) -> (Sub32 y x)
 (Neg64 (Sub64 x y)) -> (Sub64 y x)
+(Add8  (Const8  [1]) (Com8  x)) -> (Neg8  x)
+(Add16 (Const16 [1]) (Com16 x)) -> (Neg16 x)
+(Add32 (Const32 [1]) (Com32 x)) -> (Neg32 x)
+(Add64 (Const64 [1]) (Com64 x)) -> (Neg64 x)
 
 (And64 x (And64 x y)) -> (And64 x y)
 (And32 x (And32 x y)) -> (And32 x y)
 (Mod64u <t> x (Const64 [c])) && x.Op != OpConst64 && c > 0 && umagicOK(64,c)
   -> (Sub64 x (Mul64 <t> (Div64u <t> x (Const64 <t> [c])) (Const64 <t> [c])))
 
+// Reassociate expressions involving
+// constants such that constants come first,
+// exposing obvious constant-folding opportunities.
+// First, re-write (op x (op y z)) to (op (op y z) x) if
+// the op is commutative, to reduce the number of subsequent
+// matching rules for folding. Then, reassociate
+// (op (op y C) x) to (op C (op x y)) or similar, where C
+// is constant, which pushes constants to the outside
+// of the expression. At that point, any constant-folding
+// opportunities should be obvious.
+
+(Add64 x l:(Add64 _ _)) && (x.Op != OpAdd64 && x.Op != OpConst64) -> (Add64 l x)
+(Add32 x l:(Add32 _ _)) && (x.Op != OpAdd32 && x.Op != OpConst32) -> (Add32 l x)
+(Add16 x l:(Add16 _ _)) && (x.Op != OpAdd16 && x.Op != OpConst16) -> (Add16 l x)
+(Add8  x l:(Add8  _ _)) && (x.Op != OpAdd8  && x.Op != OpConst8)  -> (Add8  l x)
+(And64 x l:(And64 _ _)) && (x.Op != OpAnd64 && x.Op != OpConst64) -> (And64 l x)
+(And32 x l:(And32 _ _)) && (x.Op != OpAnd32 && x.Op != OpConst32) -> (And32 l x)
+(And16 x l:(And16 _ _)) && (x.Op != OpAnd16 && x.Op != OpConst16) -> (And16 l x)
+(And8  x l:(And8  _ _)) && (x.Op != OpAnd8  && x.Op != OpConst8)  -> (And8  l x)
+(Or64 x l:(Or64 _ _)) && (x.Op != OpOr64 && x.Op != OpConst64) -> (Or64 l x)
+(Or32 x l:(Or32 _ _)) && (x.Op != OpOr32 && x.Op != OpConst32) -> (Or32 l x)
+(Or16 x l:(Or16 _ _)) && (x.Op != OpOr16 && x.Op != OpConst16) -> (Or16 l x)
+(Or8  x l:(Or8  _ _)) && (x.Op != OpOr8  && x.Op != OpConst8)  -> (Or8  l x)
+(Xor64 x l:(Xor64 _ _)) && (x.Op != OpXor64 && x.Op != OpConst64) -> (Xor64 l x)
+(Xor32 x l:(Xor32 _ _)) && (x.Op != OpXor32 && x.Op != OpConst32) -> (Xor32 l x)
+(Xor16 x l:(Xor16 _ _)) && (x.Op != OpXor16 && x.Op != OpConst16) -> (Xor16 l x)
+(Xor8  x l:(Xor8  _ _)) && (x.Op != OpXor8  && x.Op != OpConst8)  -> (Xor8  l x)
+(Mul64 x l:(Mul64 _ _)) && (x.Op != OpMul64 && x.Op != OpConst64) -> (Mul64 l x)
+(Mul32 x l:(Mul32 _ _)) && (x.Op != OpMul32 && x.Op != OpConst32) -> (Mul32 l x)
+(Mul16 x l:(Mul16 _ _)) && (x.Op != OpMul16 && x.Op != OpConst16) -> (Mul16 l x)
+(Mul8  x l:(Mul8  _ _)) && (x.Op != OpMul8  && x.Op != OpConst8)  -> (Mul8  l x)
+
+// x + (C + z) -> C + (x + z)
+(Add64 (Add64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Add64 i (Add64 <t> z x))
+(Add32 (Add32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Add32 i (Add32 <t> z x))
+(Add16 (Add16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Add16 i (Add16 <t> z x))
+(Add8  (Add8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  -> (Add8  i (Add8  <t> z x))
+
+// x + (C - z) -> C + (x - z)
+(Add64 (Sub64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Add64 i (Sub64 <t> x z))
+(Add32 (Sub32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Add32 i (Sub32 <t> x z))
+(Add16 (Sub16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Add16 i (Sub16 <t> x z))
+(Add8  (Sub8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  -> (Add8  i (Sub8  <t> x z))
+(Add64 x (Sub64 i:(Const64 <t>) z)) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Add64 i (Sub64 <t> x z))
+(Add32 x (Sub32 i:(Const32 <t>) z)) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Add32 i (Sub32 <t> x z))
+(Add16 x (Sub16 i:(Const16 <t>) z)) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Add16 i (Sub16 <t> x z))
+(Add8  x (Sub8  i:(Const8  <t>) z)) && (z.Op != OpConst8  && x.Op != OpConst8)  -> (Add8  i (Sub8  <t> x z))
+
+// x + (z - C) -> (x + z) - C
+(Add64 (Sub64 z i:(Const64 <t>)) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Sub64 (Add64 <t> x z) i)
+(Add32 (Sub32 z i:(Const32 <t>)) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Sub32 (Add32 <t> x z) i)
+(Add16 (Sub16 z i:(Const16 <t>)) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Sub16 (Add16 <t> x z) i)
+(Add8  (Sub8  z i:(Const8  <t>)) x) && (z.Op != OpConst8  && x.Op != OpConst8)  -> (Sub8  (Add8  <t> x z) i)
+(Add64 x (Sub64 z i:(Const64 <t>))) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Sub64 (Add64 <t> x z) i)
+(Add32 x (Sub32 z i:(Const32 <t>))) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Sub32 (Add32 <t> x z) i)
+(Add16 x (Sub16 z i:(Const16 <t>))) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Sub16 (Add16 <t> x z) i)
+(Add8  x (Sub8  z i:(Const8  <t>))) && (z.Op != OpConst8  && x.Op != OpConst8)  -> (Sub8  (Add8  <t> x z) i)
+
+// x - (C - z) -> x + (z - C) -> (x + z) - C
+(Sub64 x (Sub64 i:(Const64 <t>) z)) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Sub64 (Add64 <t> x z) i)
+(Sub32 x (Sub32 i:(Const32 <t>) z)) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Sub32 (Add32 <t> x z) i)
+(Sub16 x (Sub16 i:(Const16 <t>) z)) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Sub16 (Add16 <t> x z) i)
+(Sub8  x (Sub8  i:(Const8  <t>) z)) && (z.Op != OpConst8  && x.Op != OpConst8)  -> (Sub8  (Add8  <t> x z) i)
+
+// x - (z - C) -> x + (C - z) -> (x - z) + C
+(Sub64 x (Sub64 z i:(Const64 <t>))) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Add64 i (Sub64 <t> x z))
+(Sub32 x (Sub32 z i:(Const32 <t>))) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Add32 i (Sub32 <t> x z))
+(Sub16 x (Sub16 z i:(Const16 <t>))) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Add16 i (Sub16 <t> x z))
+(Sub8  x (Sub8  z i:(Const8  <t>))) && (z.Op != OpConst8  && x.Op != OpConst8)  -> (Add8  i (Sub8  <t> x z))
+
+// x & (C & z) -> C & (x & z)
+(And64 (And64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (And64 i (And64 <t> z x))
+(And32 (And32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (And32 i (And32 <t> z x))
+(And16 (And16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (And16 i (And16 <t> z x))
+(And8  (And8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  -> (And8  i (And8  <t> z x))
+
+// x | (C | z) -> C | (x | z)
+(Or64 (Or64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Or64 i (Or64 <t> z x))
+(Or32 (Or32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Or32 i (Or32 <t> z x))
+(Or16 (Or16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Or16 i (Or16 <t> z x))
+(Or8  (Or8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  -> (Or8  i (Or8  <t> z x))
+
+// x ^ (C ^ z) -> C ^ (x ^ z)
+(Xor64 (Xor64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Xor64 i (Xor64 <t> z x))
+(Xor32 (Xor32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Xor32 i (Xor32 <t> z x))
+(Xor16 (Xor16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Xor16 i (Xor16 <t> z x))
+(Xor8  (Xor8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  -> (Xor8  i (Xor8  <t> z x))
+
+// C + (D + x) -> (C + D) + x
+(Add64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) -> (Add64 (Const64 <t> [c+d]) x)
+(Add32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) -> (Add32 (Const32 <t> [int64(int32(c+d))]) x)
+(Add16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x)) -> (Add16 (Const16 <t> [int64(int16(c+d))]) x)
+(Add8  (Const8  <t> [c]) (Add8  (Const8  <t> [d]) x)) -> (Add8  (Const8  <t> [int64(int8(c+d))]) x)
+
+// C + (D - x) -> (C + D) - x
+(Add64 (Const64 <t> [c]) (Sub64 (Const64 <t> [d]) x)) -> (Sub64 (Const64 <t> [c+d]) x)
+(Add32 (Const32 <t> [c]) (Sub32 (Const32 <t> [d]) x)) -> (Sub32 (Const32 <t> [int64(int32(c+d))]) x)
+(Add16 (Const16 <t> [c]) (Sub16 (Const16 <t> [d]) x)) -> (Sub16 (Const16 <t> [int64(int16(c+d))]) x)
+(Add8  (Const8  <t> [c]) (Sub8  (Const8  <t> [d]) x)) -> (Sub8  (Const8  <t> [int64(int8(c+d))]) x)
+
+// C + (x - D) -> (C - D) + x
+(Add64 (Const64 <t> [c]) (Sub64 x (Const64 <t> [d]))) -> (Add64 (Const64 <t> [c-d]) x)
+(Add32 (Const32 <t> [c]) (Sub32 x (Const32 <t> [d]))) -> (Add32 (Const32 <t> [int64(int32(c-d))]) x)
+(Add16 (Const16 <t> [c]) (Sub16 x (Const16 <t> [d]))) -> (Add16 (Const16 <t> [int64(int16(c-d))]) x)
+(Add8  (Const8  <t> [c]) (Sub8  x (Const8  <t> [d]))) -> (Add8  (Const8  <t> [int64(int8(c-d))]) x)
+
+// C - (x - D) -> (C + D) - x
+(Sub64 (Const64 <t> [c]) (Sub64 x (Const64 <t> [d]))) -> (Sub64 (Const64 <t> [c+d]) x)
+(Sub32 (Const32 <t> [c]) (Sub32 x (Const32 <t> [d]))) -> (Sub32 (Const32 <t> [int64(int32(c+d))]) x)
+(Sub16 (Const16 <t> [c]) (Sub16 x (Const16 <t> [d]))) -> (Sub16 (Const16 <t> [int64(int16(c+d))]) x)
+(Sub8  (Const8  <t> [c]) (Sub8  x (Const8  <t> [d]))) -> (Sub8  (Const8  <t> [int64(int8(c+d))]) x)
+
+// C - (D - x) -> (C - D) + x
+(Sub64 (Const64 <t> [c]) (Sub64 (Const64 <t> [d]) x)) -> (Add64 (Const64 <t> [c-d]) x)
+(Sub32 (Const32 <t> [c]) (Sub32 (Const32 <t> [d]) x)) -> (Add32 (Const32 <t> [int64(int32(c-d))]) x)
+(Sub16 (Const16 <t> [c]) (Sub16 (Const16 <t> [d]) x)) -> (Add16 (Const16 <t> [int64(int16(c-d))]) x)
+(Sub8  (Const8  <t> [c]) (Sub8  (Const8  <t> [d]) x)) -> (Add8  (Const8  <t> [int64(int8(c-d))]) x)
+
+// C & (D & x) -> (C & D) & x
+(And64 (Const64 <t> [c]) (And64 (Const64 <t> [d]) x)) -> (And64 (Const64 <t> [c&d]) x)
+(And32 (Const32 <t> [c]) (And32 (Const32 <t> [d]) x)) -> (And32 (Const32 <t> [int64(int32(c&d))]) x)
+(And16 (Const16 <t> [c]) (And16 (Const16 <t> [d]) x)) -> (And16 (Const16 <t> [int64(int16(c&d))]) x)
+(And8  (Const8  <t> [c]) (And8  (Const8  <t> [d]) x)) -> (And8  (Const8  <t> [int64(int8(c&d))]) x)
+
+// C | (D | x) -> (C | D) | x
+(Or64 (Const64 <t> [c]) (Or64 (Const64 <t> [d]) x)) -> (Or64 (Const64 <t> [c|d]) x)
+(Or32 (Const32 <t> [c]) (Or32 (Const32 <t> [d]) x)) -> (Or32 (Const32 <t> [int64(int32(c|d))]) x)
+(Or16 (Const16 <t> [c]) (Or16 (Const16 <t> [d]) x)) -> (Or16 (Const16 <t> [int64(int16(c|d))]) x)
+(Or8  (Const8  <t> [c]) (Or8  (Const8  <t> [d]) x)) -> (Or8  (Const8  <t> [int64(int8(c|d))]) x)
+
+// C ^ (D ^ x) -> (C ^ D) ^ x
+(Xor64 (Const64 <t> [c]) (Xor64 (Const64 <t> [d]) x)) -> (Xor64 (Const64 <t> [c^d]) x)
+(Xor32 (Const32 <t> [c]) (Xor32 (Const32 <t> [d]) x)) -> (Xor32 (Const32 <t> [int64(int32(c^d))]) x)
+(Xor16 (Const16 <t> [c]) (Xor16 (Const16 <t> [d]) x)) -> (Xor16 (Const16 <t> [int64(int16(c^d))]) x)
+(Xor8  (Const8  <t> [c]) (Xor8  (Const8  <t> [d]) x)) -> (Xor8  (Const8  <t> [int64(int8(c^d))]) x)
+
+// C * (D * x) = (C * D) * x
+(Mul64 (Const64 <t> [c]) (Mul64 (Const64 <t> [d]) x)) -> (Mul64 (Const64 <t> [c*d]) x)
+(Mul32 (Const32 <t> [c]) (Mul32 (Const32 <t> [d]) x)) -> (Mul32 (Const32 <t> [int64(int32(c*d))]) x)
+(Mul16 (Const16 <t> [c]) (Mul16 (Const16 <t> [d]) x)) -> (Mul16 (Const16 <t> [int64(int16(c*d))]) x)
+(Mul8  (Const8  <t> [c]) (Mul8  (Const8  <t> [d]) x)) -> (Mul8  (Const8  <t> [int64(int8(c*d))]) x)
+
 // floating point optimizations
 (Add32F x (Const32F [0])) -> x
 (Add32F (Const32F [0]) x) -> x
index 3033a31f98898bf810b0b33db15a5fb3aee7cc04..f17bf3343cac378cda48350f0bfed9a248ca2673 100644 (file)
@@ -476,6 +476,263 @@ func rewriteValuegeneric_OpAdd16(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
+       // match: (Add16 (Const16 [1]) (Com16 x))
+       // cond:
+       // result: (Neg16 x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               if v_0.AuxInt != 1 {
+                       break
+               }
+               v_1 := v.Args[1]
+               if v_1.Op != OpCom16 {
+                       break
+               }
+               x := v_1.Args[0]
+               v.reset(OpNeg16)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add16 x l:(Add16 _ _))
+       // cond: (x.Op != OpAdd16 && x.Op != OpConst16)
+       // result: (Add16 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpAdd16 {
+                       break
+               }
+               if !(x.Op != OpAdd16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpAdd16)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add16 (Add16 i:(Const16 <t>) z) x)
+       // cond: (z.Op != OpConst16 && x.Op != OpConst16)
+       // result: (Add16 i (Add16 <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpAdd16 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst16 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpAdd16)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpAdd16, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Add16 (Sub16 i:(Const16 <t>) z) x)
+       // cond: (z.Op != OpConst16 && x.Op != OpConst16)
+       // result: (Add16 i (Sub16 <t> x z))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpSub16 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst16 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpAdd16)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub16, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Add16 x (Sub16 i:(Const16 <t>) z))
+       // cond: (z.Op != OpConst16 && x.Op != OpConst16)
+       // result: (Add16 i (Sub16 <t> x z))
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub16 {
+                       break
+               }
+               i := v_1.Args[0]
+               if i.Op != OpConst16 {
+                       break
+               }
+               t := i.Type
+               z := v_1.Args[1]
+               if !(z.Op != OpConst16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpAdd16)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub16, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Add16 (Sub16 z i:(Const16 <t>)) x)
+       // cond: (z.Op != OpConst16 && x.Op != OpConst16)
+       // result: (Sub16 (Add16 <t> x z) i)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpSub16 {
+                       break
+               }
+               z := v_0.Args[0]
+               i := v_0.Args[1]
+               if i.Op != OpConst16 {
+                       break
+               }
+               t := i.Type
+               x := v.Args[1]
+               if !(z.Op != OpConst16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpSub16)
+               v0 := b.NewValue0(v.Pos, OpAdd16, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
+               return true
+       }
+       // match: (Add16 x (Sub16 z i:(Const16 <t>)))
+       // cond: (z.Op != OpConst16 && x.Op != OpConst16)
+       // result: (Sub16 (Add16 <t> x z) i)
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub16 {
+                       break
+               }
+               z := v_1.Args[0]
+               i := v_1.Args[1]
+               if i.Op != OpConst16 {
+                       break
+               }
+               t := i.Type
+               if !(z.Op != OpConst16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpSub16)
+               v0 := b.NewValue0(v.Pos, OpAdd16, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
+               return true
+       }
+       // match: (Add16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x))
+       // cond:
+       // result: (Add16 (Const16 <t> [int64(int16(c+d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAdd16 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst16 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpAdd16)
+               v0 := b.NewValue0(v.Pos, OpConst16, t)
+               v0.AuxInt = int64(int16(c + d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add16 (Const16 <t> [c]) (Sub16 (Const16 <t> [d]) x))
+       // cond:
+       // result: (Sub16 (Const16 <t> [int64(int16(c+d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub16 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst16 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpSub16)
+               v0 := b.NewValue0(v.Pos, OpConst16, t)
+               v0.AuxInt = int64(int16(c + d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add16 (Const16 <t> [c]) (Sub16 x (Const16 <t> [d])))
+       // cond:
+       // result: (Add16 (Const16 <t> [int64(int16(c-d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub16 {
+                       break
+               }
+               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
+               }
+               d := v_1_1.AuxInt
+               v.reset(OpAdd16)
+               v0 := b.NewValue0(v.Pos, OpConst16, t)
+               v0.AuxInt = int64(int16(c - d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpAdd32(v *Value, config *Config) bool {
@@ -537,239 +794,1010 @@ func rewriteValuegeneric_OpAdd32(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
-       return false
-}
-func rewriteValuegeneric_OpAdd32F(v *Value, config *Config) bool {
-       b := v.Block
-       _ = b
-       // match: (Add32F (Const32F [c]) (Const32F [d]))
+       // match: (Add32 (Const32 [1]) (Com32 x))
        // cond:
-       // result: (Const32F [f2i(float64(i2f32(c) + i2f32(d)))])
+       // result: (Neg32 x)
        for {
                v_0 := v.Args[0]
-               if v_0.Op != OpConst32F {
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               if v_0.AuxInt != 1 {
                        break
                }
-               c := v_0.AuxInt
                v_1 := v.Args[1]
-               if v_1.Op != OpConst32F {
+               if v_1.Op != OpCom32 {
                        break
                }
-               d := v_1.AuxInt
-               v.reset(OpConst32F)
-               v.AuxInt = f2i(float64(i2f32(c) + i2f32(d)))
+               x := v_1.Args[0]
+               v.reset(OpNeg32)
+               v.AddArg(x)
                return true
        }
-       // match: (Add32F x (Const32F [0]))
-       // cond:
-       // result: x
+       // match: (Add32 x l:(Add32 _ _))
+       // cond: (x.Op != OpAdd32 && x.Op != OpConst32)
+       // result: (Add32 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpAdd32 {
+                       break
+               }
+               if !(x.Op != OpAdd32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpAdd32)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add32 (Add32 i:(Const32 <t>) z) x)
+       // cond: (z.Op != OpConst32 && x.Op != OpConst32)
+       // result: (Add32 i (Add32 <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpAdd32 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst32 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpAdd32)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpAdd32, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Add32 (Sub32 i:(Const32 <t>) z) x)
+       // cond: (z.Op != OpConst32 && x.Op != OpConst32)
+       // result: (Add32 i (Sub32 <t> x z))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpSub32 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst32 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpAdd32)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub32, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Add32 x (Sub32 i:(Const32 <t>) z))
+       // cond: (z.Op != OpConst32 && x.Op != OpConst32)
+       // result: (Add32 i (Sub32 <t> x z))
        for {
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpConst32F {
+               if v_1.Op != OpSub32 {
                        break
                }
-               if v_1.AuxInt != 0 {
+               i := v_1.Args[0]
+               if i.Op != OpConst32 {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
+               t := i.Type
+               z := v_1.Args[1]
+               if !(z.Op != OpConst32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpAdd32)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub32, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Add32 (Sub32 z i:(Const32 <t>)) x)
+       // cond: (z.Op != OpConst32 && x.Op != OpConst32)
+       // result: (Sub32 (Add32 <t> x z) i)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpSub32 {
+                       break
+               }
+               z := v_0.Args[0]
+               i := v_0.Args[1]
+               if i.Op != OpConst32 {
+                       break
+               }
+               t := i.Type
+               x := v.Args[1]
+               if !(z.Op != OpConst32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpSub32)
+               v0 := b.NewValue0(v.Pos, OpAdd32, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
+               return true
+       }
+       // match: (Add32 x (Sub32 z i:(Const32 <t>)))
+       // cond: (z.Op != OpConst32 && x.Op != OpConst32)
+       // result: (Sub32 (Add32 <t> x z) i)
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub32 {
+                       break
+               }
+               z := v_1.Args[0]
+               i := v_1.Args[1]
+               if i.Op != OpConst32 {
+                       break
+               }
+               t := i.Type
+               if !(z.Op != OpConst32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpSub32)
+               v0 := b.NewValue0(v.Pos, OpAdd32, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
+               return true
+       }
+       // match: (Add32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x))
+       // cond:
+       // result: (Add32 (Const32 <t> [int64(int32(c+d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAdd32 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst32 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpAdd32)
+               v0 := b.NewValue0(v.Pos, OpConst32, t)
+               v0.AuxInt = int64(int32(c + d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add32 (Const32 <t> [c]) (Sub32 (Const32 <t> [d]) x))
+       // cond:
+       // result: (Sub32 (Const32 <t> [int64(int32(c+d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub32 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst32 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpSub32)
+               v0 := b.NewValue0(v.Pos, OpConst32, t)
+               v0.AuxInt = int64(int32(c + d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add32 (Const32 <t> [c]) (Sub32 x (Const32 <t> [d])))
+       // cond:
+       // result: (Add32 (Const32 <t> [int64(int32(c-d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub32 {
+                       break
+               }
+               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
+               }
+               d := v_1_1.AuxInt
+               v.reset(OpAdd32)
+               v0 := b.NewValue0(v.Pos, OpConst32, t)
+               v0.AuxInt = int64(int32(c - d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpAdd32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Add32F (Const32F [c]) (Const32F [d]))
+       // cond:
+       // result: (Const32F [f2i(float64(i2f32(c) + i2f32(d)))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32F {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst32F {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst32F)
+               v.AuxInt = f2i(float64(i2f32(c) + i2f32(d)))
+               return true
+       }
+       // match: (Add32F x (Const32F [0]))
+       // cond:
+       // result: x
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst32F {
+                       break
+               }
+               if v_1.AuxInt != 0 {
+                       break
+               }
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add32F (Const32F [0]) x)
+       // cond:
+       // result: x
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32F {
+                       break
+               }
+               if v_0.AuxInt != 0 {
+                       break
+               }
+               x := v.Args[1]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpAdd64(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Add64  (Const64 [c])  (Const64 [d]))
+       // cond:
+       // result: (Const64 [c+d])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst64)
+               v.AuxInt = c + d
+               return true
+       }
+       // match: (Add64 x (Const64 <t> [c]))
+       // cond: x.Op != OpConst64
+       // result: (Add64 (Const64 <t> [c]) x)
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               t := v_1.Type
+               c := v_1.AuxInt
+               if !(x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpAdd64)
+               v0 := b.NewValue0(v.Pos, OpConst64, t)
+               v0.AuxInt = c
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add64 (Const64 [0]) x)
+       // cond:
+       // result: x
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               if v_0.AuxInt != 0 {
+                       break
+               }
+               x := v.Args[1]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add64 (Const64 [1]) (Com64 x))
+       // cond:
+       // result: (Neg64 x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               if v_0.AuxInt != 1 {
+                       break
+               }
+               v_1 := v.Args[1]
+               if v_1.Op != OpCom64 {
+                       break
+               }
+               x := v_1.Args[0]
+               v.reset(OpNeg64)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add64 x l:(Add64 _ _))
+       // cond: (x.Op != OpAdd64 && x.Op != OpConst64)
+       // result: (Add64 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpAdd64 {
+                       break
+               }
+               if !(x.Op != OpAdd64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpAdd64)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add64 (Add64 i:(Const64 <t>) z) x)
+       // cond: (z.Op != OpConst64 && x.Op != OpConst64)
+       // result: (Add64 i (Add64 <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpAdd64 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst64 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpAdd64)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpAdd64, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Add64 (Sub64 i:(Const64 <t>) z) x)
+       // cond: (z.Op != OpConst64 && x.Op != OpConst64)
+       // result: (Add64 i (Sub64 <t> x z))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpSub64 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst64 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpAdd64)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub64, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Add64 x (Sub64 i:(Const64 <t>) z))
+       // cond: (z.Op != OpConst64 && x.Op != OpConst64)
+       // result: (Add64 i (Sub64 <t> x z))
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub64 {
+                       break
+               }
+               i := v_1.Args[0]
+               if i.Op != OpConst64 {
+                       break
+               }
+               t := i.Type
+               z := v_1.Args[1]
+               if !(z.Op != OpConst64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpAdd64)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub64, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Add64 (Sub64 z i:(Const64 <t>)) x)
+       // cond: (z.Op != OpConst64 && x.Op != OpConst64)
+       // result: (Sub64 (Add64 <t> x z) i)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpSub64 {
+                       break
+               }
+               z := v_0.Args[0]
+               i := v_0.Args[1]
+               if i.Op != OpConst64 {
+                       break
+               }
+               t := i.Type
+               x := v.Args[1]
+               if !(z.Op != OpConst64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpSub64)
+               v0 := b.NewValue0(v.Pos, OpAdd64, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
+               return true
+       }
+       // match: (Add64 x (Sub64 z i:(Const64 <t>)))
+       // cond: (z.Op != OpConst64 && x.Op != OpConst64)
+       // result: (Sub64 (Add64 <t> x z) i)
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub64 {
+                       break
+               }
+               z := v_1.Args[0]
+               i := v_1.Args[1]
+               if i.Op != OpConst64 {
+                       break
+               }
+               t := i.Type
+               if !(z.Op != OpConst64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpSub64)
+               v0 := b.NewValue0(v.Pos, OpAdd64, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
+               return true
+       }
+       // match: (Add64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x))
+       // cond:
+       // result: (Add64 (Const64 <t> [c+d]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAdd64 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst64 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpAdd64)
+               v0 := b.NewValue0(v.Pos, OpConst64, t)
+               v0.AuxInt = c + d
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add64 (Const64 <t> [c]) (Sub64 (Const64 <t> [d]) x))
+       // cond:
+       // result: (Sub64 (Const64 <t> [c+d]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub64 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst64 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpSub64)
+               v0 := b.NewValue0(v.Pos, OpConst64, t)
+               v0.AuxInt = c + d
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add64 (Const64 <t> [c]) (Sub64 x (Const64 <t> [d])))
+       // cond:
+       // result: (Add64 (Const64 <t> [c-d]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub64 {
+                       break
+               }
+               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
+               }
+               d := v_1_1.AuxInt
+               v.reset(OpAdd64)
+               v0 := b.NewValue0(v.Pos, OpConst64, t)
+               v0.AuxInt = c - d
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpAdd64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Add64F (Const64F [c]) (Const64F [d]))
+       // cond:
+       // result: (Const64F [f2i(i2f(c) + i2f(d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64F {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64F {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst64F)
+               v.AuxInt = f2i(i2f(c) + i2f(d))
+               return true
+       }
+       // match: (Add64F x (Const64F [0]))
+       // cond:
+       // result: x
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64F {
+                       break
+               }
+               if v_1.AuxInt != 0 {
+                       break
+               }
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add64F (Const64F [0]) x)
+       // cond:
+       // result: x
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64F {
+                       break
+               }
+               if v_0.AuxInt != 0 {
+                       break
+               }
+               x := v.Args[1]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpAdd8(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Add8   (Const8 [c])   (Const8 [d]))
+       // cond:
+       // result: (Const8  [int64(int8(c+d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst8 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst8)
+               v.AuxInt = int64(int8(c + d))
+               return true
+       }
+       // match: (Add8  x (Const8  <t> [c]))
+       // cond: x.Op != OpConst8
+       // result: (Add8  (Const8  <t> [c]) x)
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst8 {
+                       break
+               }
+               t := v_1.Type
+               c := v_1.AuxInt
+               if !(x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpAdd8)
+               v0 := b.NewValue0(v.Pos, OpConst8, t)
+               v0.AuxInt = c
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add8  (Const8  [0]) x)
+       // cond:
+       // result: x
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               if v_0.AuxInt != 0 {
+                       break
+               }
+               x := v.Args[1]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add8  (Const8  [1]) (Com8  x))
+       // cond:
+       // result: (Neg8  x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               if v_0.AuxInt != 1 {
+                       break
+               }
+               v_1 := v.Args[1]
+               if v_1.Op != OpCom8 {
+                       break
+               }
+               x := v_1.Args[0]
+               v.reset(OpNeg8)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Add8  x l:(Add8  _ _))
+       // cond: (x.Op != OpAdd8  && x.Op != OpConst8)
+       // result: (Add8  l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpAdd8 {
+                       break
+               }
+               if !(x.Op != OpAdd8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpAdd8)
+               v.AddArg(l)
                v.AddArg(x)
                return true
        }
-       // match: (Add32F (Const32F [0]) x)
-       // cond:
-       // result: x
+       // match: (Add8  (Add8  i:(Const8  <t>) z) x)
+       // cond: (z.Op != OpConst8  && x.Op != OpConst8)
+       // result: (Add8  i (Add8  <t> z x))
        for {
                v_0 := v.Args[0]
-               if v_0.Op != OpConst32F {
+               if v_0.Op != OpAdd8 {
                        break
                }
-               if v_0.AuxInt != 0 {
+               i := v_0.Args[0]
+               if i.Op != OpConst8 {
                        break
                }
+               t := i.Type
+               z := v_0.Args[1]
                x := v.Args[1]
-               v.reset(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
+               if !(z.Op != OpConst8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpAdd8)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpAdd8, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
                return true
        }
-       return false
-}
-func rewriteValuegeneric_OpAdd64(v *Value, config *Config) bool {
-       b := v.Block
-       _ = b
-       // match: (Add64  (Const64 [c])  (Const64 [d]))
-       // cond:
-       // result: (Const64 [c+d])
+       // match: (Add8  (Sub8  i:(Const8  <t>) z) x)
+       // cond: (z.Op != OpConst8  && x.Op != OpConst8)
+       // result: (Add8  i (Sub8  <t> x z))
        for {
                v_0 := v.Args[0]
-               if v_0.Op != OpConst64 {
+               if v_0.Op != OpSub8 {
                        break
                }
-               c := v_0.AuxInt
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
+               i := v_0.Args[0]
+               if i.Op != OpConst8 {
                        break
                }
-               d := v_1.AuxInt
-               v.reset(OpConst64)
-               v.AuxInt = c + d
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpAdd8)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub8, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
                return true
        }
-       // match: (Add64 x (Const64 <t> [c]))
-       // cond: x.Op != OpConst64
-       // result: (Add64 (Const64 <t> [c]) x)
+       // match: (Add8  x (Sub8  i:(Const8  <t>) z))
+       // cond: (z.Op != OpConst8  && x.Op != OpConst8)
+       // result: (Add8  i (Sub8  <t> x z))
        for {
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpConst64 {
+               if v_1.Op != OpSub8 {
                        break
                }
-               t := v_1.Type
-               c := v_1.AuxInt
-               if !(x.Op != OpConst64) {
+               i := v_1.Args[0]
+               if i.Op != OpConst8 {
                        break
                }
-               v.reset(OpAdd64)
-               v0 := b.NewValue0(v.Pos, OpConst64, t)
-               v0.AuxInt = c
+               t := i.Type
+               z := v_1.Args[1]
+               if !(z.Op != OpConst8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpAdd8)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub8, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
                v.AddArg(v0)
-               v.AddArg(x)
                return true
        }
-       // match: (Add64 (Const64 [0]) x)
-       // cond:
-       // result: x
+       // match: (Add8  (Sub8  z i:(Const8  <t>)) x)
+       // cond: (z.Op != OpConst8  && x.Op != OpConst8)
+       // result: (Sub8  (Add8  <t> x z) i)
        for {
                v_0 := v.Args[0]
-               if v_0.Op != OpConst64 {
+               if v_0.Op != OpSub8 {
                        break
                }
-               if v_0.AuxInt != 0 {
+               z := v_0.Args[0]
+               i := v_0.Args[1]
+               if i.Op != OpConst8 {
                        break
                }
+               t := i.Type
                x := v.Args[1]
-               v.reset(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
-               return true
-       }
-       return false
-}
-func rewriteValuegeneric_OpAdd64F(v *Value, config *Config) bool {
-       b := v.Block
-       _ = b
-       // match: (Add64F (Const64F [c]) (Const64F [d]))
-       // cond:
-       // result: (Const64F [f2i(i2f(c) + i2f(d))])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpConst64F {
-                       break
-               }
-               c := v_0.AuxInt
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst64F {
+               if !(z.Op != OpConst8 && x.Op != OpConst8) {
                        break
                }
-               d := v_1.AuxInt
-               v.reset(OpConst64F)
-               v.AuxInt = f2i(i2f(c) + i2f(d))
+               v.reset(OpSub8)
+               v0 := b.NewValue0(v.Pos, OpAdd8, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
                return true
        }
-       // match: (Add64F x (Const64F [0]))
-       // cond:
-       // result: x
+       // match: (Add8  x (Sub8  z i:(Const8  <t>)))
+       // cond: (z.Op != OpConst8  && x.Op != OpConst8)
+       // result: (Sub8  (Add8  <t> x z) i)
        for {
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpConst64F {
+               if v_1.Op != OpSub8 {
                        break
                }
-               if v_1.AuxInt != 0 {
+               z := v_1.Args[0]
+               i := v_1.Args[1]
+               if i.Op != OpConst8 {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
+               t := i.Type
+               if !(z.Op != OpConst8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpSub8)
+               v0 := b.NewValue0(v.Pos, OpAdd8, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
                return true
        }
-       // match: (Add64F (Const64F [0]) x)
+       // match: (Add8  (Const8  <t> [c]) (Add8  (Const8  <t> [d]) x))
        // cond:
-       // result: x
+       // result: (Add8  (Const8  <t> [int64(int8(c+d))]) x)
        for {
                v_0 := v.Args[0]
-               if v_0.Op != OpConst64F {
+               if v_0.Op != OpConst8 {
                        break
                }
-               if v_0.AuxInt != 0 {
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAdd8 {
                        break
                }
-               x := v.Args[1]
-               v.reset(OpCopy)
-               v.Type = x.Type
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst8 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpAdd8)
+               v0 := b.NewValue0(v.Pos, OpConst8, t)
+               v0.AuxInt = int64(int8(c + d))
+               v.AddArg(v0)
                v.AddArg(x)
                return true
        }
-       return false
-}
-func rewriteValuegeneric_OpAdd8(v *Value, config *Config) bool {
-       b := v.Block
-       _ = b
-       // match: (Add8   (Const8 [c])   (Const8 [d]))
+       // match: (Add8  (Const8  <t> [c]) (Sub8  (Const8  <t> [d]) x))
        // cond:
-       // result: (Const8  [int64(int8(c+d))])
+       // result: (Sub8  (Const8  <t> [int64(int8(c+d))]) x)
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpConst8 {
                        break
                }
+               t := v_0.Type
                c := v_0.AuxInt
                v_1 := v.Args[1]
-               if v_1.Op != OpConst8 {
+               if v_1.Op != OpSub8 {
                        break
                }
-               d := v_1.AuxInt
-               v.reset(OpConst8)
-               v.AuxInt = int64(int8(c + d))
-               return true
-       }
-       // match: (Add8  x (Const8  <t> [c]))
-       // cond: x.Op != OpConst8
-       // result: (Add8  (Const8  <t> [c]) x)
-       for {
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpConst8 {
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst8 {
                        break
                }
-               t := v_1.Type
-               c := v_1.AuxInt
-               if !(x.Op != OpConst8) {
+               if v_1_0.Type != t {
                        break
                }
-               v.reset(OpAdd8)
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpSub8)
                v0 := b.NewValue0(v.Pos, OpConst8, t)
-               v0.AuxInt = c
+               v0.AuxInt = int64(int8(c + d))
                v.AddArg(v0)
                v.AddArg(x)
                return true
        }
-       // match: (Add8  (Const8  [0]) x)
+       // match: (Add8  (Const8  <t> [c]) (Sub8  x (Const8  <t> [d])))
        // cond:
-       // result: x
+       // result: (Add8  (Const8  <t> [int64(int8(c-d))]) x)
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpConst8 {
                        break
                }
-               if v_0.AuxInt != 0 {
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub8 {
                        break
                }
-               x := v.Args[1]
-               v.reset(OpCopy)
-               v.Type = x.Type
+               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
+               }
+               d := v_1_1.AuxInt
+               v.reset(OpAdd8)
+               v0 := b.NewValue0(v.Pos, OpConst8, t)
+               v0.AuxInt = int64(int8(c - d))
+               v.AddArg(v0)
                v.AddArg(x)
                return true
        }
@@ -800,6 +1828,24 @@ func rewriteValuegeneric_OpAddPtr(v *Value, config *Config) bool {
 func rewriteValuegeneric_OpAnd16(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (And16  (Const16 [c])  (Const16 [d]))
+       // cond:
+       // result: (Const16 [int64(int16(c&d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst16 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst16)
+               v.AuxInt = int64(int16(c & d))
+               return true
+       }
        // match: (And16 x (Const16 <t> [c]))
        // cond: x.Op != OpConst16
        // result: (And16 (Const16 <t> [c]) x)
@@ -910,39 +1956,130 @@ func rewriteValuegeneric_OpAnd16(v *Value, config *Config) bool {
                if v_0.Op != OpAnd16 {
                        break
                }
-               x := v_0.Args[0]
-               y := v_0.Args[1]
-               if x != v.Args[1] {
+               x := v_0.Args[0]
+               y := v_0.Args[1]
+               if x != v.Args[1] {
+                       break
+               }
+               v.reset(OpAnd16)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (And16 (And16 x y) y)
+       // cond:
+       // result: (And16 x y)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd16 {
+                       break
+               }
+               x := v_0.Args[0]
+               y := v_0.Args[1]
+               if y != v.Args[1] {
+                       break
+               }
+               v.reset(OpAnd16)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (And16 x l:(And16 _ _))
+       // cond: (x.Op != OpAnd16 && x.Op != OpConst16)
+       // result: (And16 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpAnd16 {
+                       break
+               }
+               if !(x.Op != OpAnd16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpAnd16)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (And16 (And16 i:(Const16 <t>) z) x)
+       // cond: (z.Op != OpConst16 && x.Op != OpConst16)
+       // result: (And16 i (And16 <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd16 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst16 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpAnd16)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpAnd16, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (And16 (Const16 <t> [c]) (And16 (Const16 <t> [d]) x))
+       // cond:
+       // result: (And16 (Const16 <t> [int64(int16(c&d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd16 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst16 {
+                       break
+               }
+               if v_1_0.Type != t {
                        break
                }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
                v.reset(OpAnd16)
+               v0 := b.NewValue0(v.Pos, OpConst16, t)
+               v0.AuxInt = int64(int16(c & d))
+               v.AddArg(v0)
                v.AddArg(x)
-               v.AddArg(y)
                return true
        }
-       // match: (And16 (And16 x y) y)
+       return false
+}
+func rewriteValuegeneric_OpAnd32(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (And32  (Const32 [c])  (Const32 [d]))
        // cond:
-       // result: (And16 x y)
+       // result: (Const32 [int64(int32(c&d))])
        for {
                v_0 := v.Args[0]
-               if v_0.Op != OpAnd16 {
+               if v_0.Op != OpConst32 {
                        break
                }
-               x := v_0.Args[0]
-               y := v_0.Args[1]
-               if y != v.Args[1] {
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst32 {
                        break
                }
-               v.reset(OpAnd16)
-               v.AddArg(x)
-               v.AddArg(y)
+               d := v_1.AuxInt
+               v.reset(OpConst32)
+               v.AuxInt = int64(int32(c & d))
                return true
        }
-       return false
-}
-func rewriteValuegeneric_OpAnd32(v *Value, config *Config) bool {
-       b := v.Block
-       _ = b
        // match: (And32 x (Const32 <t> [c]))
        // cond: x.Op != OpConst32
        // result: (And32 (Const32 <t> [c]) x)
@@ -1081,11 +2218,102 @@ func rewriteValuegeneric_OpAnd32(v *Value, config *Config) bool {
                v.AddArg(y)
                return true
        }
+       // match: (And32 x l:(And32 _ _))
+       // cond: (x.Op != OpAnd32 && x.Op != OpConst32)
+       // result: (And32 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpAnd32 {
+                       break
+               }
+               if !(x.Op != OpAnd32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpAnd32)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (And32 (And32 i:(Const32 <t>) z) x)
+       // cond: (z.Op != OpConst32 && x.Op != OpConst32)
+       // result: (And32 i (And32 <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd32 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst32 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpAnd32)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpAnd32, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (And32 (Const32 <t> [c]) (And32 (Const32 <t> [d]) x))
+       // cond:
+       // result: (And32 (Const32 <t> [int64(int32(c&d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd32 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst32 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpAnd32)
+               v0 := b.NewValue0(v.Pos, OpConst32, t)
+               v0.AuxInt = int64(int32(c & d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpAnd64(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (And64  (Const64 [c])  (Const64 [d]))
+       // cond:
+       // result: (Const64 [c&d])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst64)
+               v.AuxInt = c & d
+               return true
+       }
        // match: (And64 x (Const64 <t> [c]))
        // cond: x.Op != OpConst64
        // result: (And64 (Const64 <t> [c]) x)
@@ -1276,11 +2504,102 @@ func rewriteValuegeneric_OpAnd64(v *Value, config *Config) bool {
                v.AddArg(v2)
                return true
        }
+       // match: (And64 x l:(And64 _ _))
+       // cond: (x.Op != OpAnd64 && x.Op != OpConst64)
+       // result: (And64 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpAnd64 {
+                       break
+               }
+               if !(x.Op != OpAnd64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpAnd64)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (And64 (And64 i:(Const64 <t>) z) x)
+       // cond: (z.Op != OpConst64 && x.Op != OpConst64)
+       // result: (And64 i (And64 <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd64 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst64 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpAnd64)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpAnd64, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (And64 (Const64 <t> [c]) (And64 (Const64 <t> [d]) x))
+       // cond:
+       // result: (And64 (Const64 <t> [c&d]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd64 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst64 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpAnd64)
+               v0 := b.NewValue0(v.Pos, OpConst64, t)
+               v0.AuxInt = c & d
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpAnd8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (And8   (Const8 [c])   (Const8 [d]))
+       // cond:
+       // result: (Const8  [int64(int8(c&d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst8 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst8)
+               v.AuxInt = int64(int8(c & d))
+               return true
+       }
        // match: (And8  x (Const8  <t> [c]))
        // cond: x.Op != OpConst8
        // result: (And8  (Const8  <t> [c]) x)
@@ -1419,6 +2738,79 @@ func rewriteValuegeneric_OpAnd8(v *Value, config *Config) bool {
                v.AddArg(y)
                return true
        }
+       // match: (And8  x l:(And8  _ _))
+       // cond: (x.Op != OpAnd8  && x.Op != OpConst8)
+       // result: (And8  l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpAnd8 {
+                       break
+               }
+               if !(x.Op != OpAnd8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpAnd8)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (And8  (And8  i:(Const8  <t>) z) x)
+       // cond: (z.Op != OpConst8  && x.Op != OpConst8)
+       // result: (And8  i (And8  <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpAnd8 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst8 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpAnd8)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpAnd8, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (And8  (Const8  <t> [c]) (And8  (Const8  <t> [d]) x))
+       // cond:
+       // result: (And8  (Const8  <t> [int64(int8(c&d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpAnd8 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst8 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpAnd8)
+               v0 := b.NewValue0(v.Pos, OpConst8, t)
+               v0.AuxInt = int64(int8(c & d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpArg(v *Value, config *Config) bool {
@@ -7007,11 +8399,58 @@ func rewriteValuegeneric_OpMul16(v *Value, config *Config) bool {
                if v_0.Op != OpConst16 {
                        break
                }
-               if v_0.AuxInt != 0 {
+               if v_0.AuxInt != 0 {
+                       break
+               }
+               v.reset(OpConst16)
+               v.AuxInt = 0
+               return true
+       }
+       // match: (Mul16 x l:(Mul16 _ _))
+       // cond: (x.Op != OpMul16 && x.Op != OpConst16)
+       // result: (Mul16 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpMul16 {
+                       break
+               }
+               if !(x.Op != OpMul16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpMul16)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Mul16 (Const16 <t> [c]) (Mul16 (Const16 <t> [d]) x))
+       // cond:
+       // result: (Mul16 (Const16 <t> [int64(int16(c*d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpMul16 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst16 {
+                       break
+               }
+               if v_1_0.Type != t {
                        break
                }
-               v.reset(OpConst16)
-               v.AuxInt = 0
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpMul16)
+               v0 := b.NewValue0(v.Pos, OpConst16, t)
+               v0.AuxInt = int64(int16(c * d))
+               v.AddArg(v0)
+               v.AddArg(x)
                return true
        }
        return false
@@ -7189,6 +8628,53 @@ func rewriteValuegeneric_OpMul32(v *Value, config *Config) bool {
                v.AuxInt = 0
                return true
        }
+       // match: (Mul32 x l:(Mul32 _ _))
+       // cond: (x.Op != OpMul32 && x.Op != OpConst32)
+       // result: (Mul32 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpMul32 {
+                       break
+               }
+               if !(x.Op != OpMul32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpMul32)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Mul32 (Const32 <t> [c]) (Mul32 (Const32 <t> [d]) x))
+       // cond:
+       // result: (Mul32 (Const32 <t> [int64(int32(c*d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpMul32 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst32 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpMul32)
+               v0 := b.NewValue0(v.Pos, OpConst32, t)
+               v0.AuxInt = int64(int32(c * d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpMul32F(v *Value, config *Config) bool {
@@ -7453,6 +8939,53 @@ func rewriteValuegeneric_OpMul64(v *Value, config *Config) bool {
                v.AuxInt = 0
                return true
        }
+       // match: (Mul64 x l:(Mul64 _ _))
+       // cond: (x.Op != OpMul64 && x.Op != OpConst64)
+       // result: (Mul64 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpMul64 {
+                       break
+               }
+               if !(x.Op != OpMul64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpMul64)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Mul64 (Const64 <t> [c]) (Mul64 (Const64 <t> [d]) x))
+       // cond:
+       // result: (Mul64 (Const64 <t> [c*d]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpMul64 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst64 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpMul64)
+               v0 := b.NewValue0(v.Pos, OpConst64, t)
+               v0.AuxInt = c * d
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpMul64F(v *Value, config *Config) bool {
@@ -7679,6 +9212,53 @@ func rewriteValuegeneric_OpMul8(v *Value, config *Config) bool {
                v.AuxInt = 0
                return true
        }
+       // match: (Mul8  x l:(Mul8  _ _))
+       // cond: (x.Op != OpMul8  && x.Op != OpConst8)
+       // result: (Mul8  l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpMul8 {
+                       break
+               }
+               if !(x.Op != OpMul8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpMul8)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Mul8  (Const8  <t> [c]) (Mul8  (Const8  <t> [d]) x))
+       // cond:
+       // result: (Mul8  (Const8  <t> [int64(int8(c*d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpMul8 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst8 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpMul8)
+               v0 := b.NewValue0(v.Pos, OpConst8, t)
+               v0.AuxInt = int64(int8(c * d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpNeg16(v *Value, config *Config) bool {
@@ -9079,6 +10659,24 @@ func rewriteValuegeneric_OpOffPtr(v *Value, config *Config) bool {
 func rewriteValuegeneric_OpOr16(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (Or16  (Const16 [c])  (Const16 [d]))
+       // cond:
+       // result: (Const16 [int64(int16(c|d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst16 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst16)
+               v.AuxInt = int64(int16(c | d))
+               return true
+       }
        // match: (Or16 x (Const16 <t> [c]))
        // cond: x.Op != OpConst16
        // result: (Or16 (Const16 <t> [c]) x)
@@ -9217,11 +10815,102 @@ func rewriteValuegeneric_OpOr16(v *Value, config *Config) bool {
                v.AddArg(y)
                return true
        }
+       // match: (Or16 x l:(Or16 _ _))
+       // cond: (x.Op != OpOr16 && x.Op != OpConst16)
+       // result: (Or16 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpOr16 {
+                       break
+               }
+               if !(x.Op != OpOr16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpOr16)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Or16 (Or16 i:(Const16 <t>) z) x)
+       // cond: (z.Op != OpConst16 && x.Op != OpConst16)
+       // result: (Or16 i (Or16 <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpOr16 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst16 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpOr16)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpOr16, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Or16 (Const16 <t> [c]) (Or16 (Const16 <t> [d]) x))
+       // cond:
+       // result: (Or16 (Const16 <t> [int64(int16(c|d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpOr16 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst16 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpOr16)
+               v0 := b.NewValue0(v.Pos, OpConst16, t)
+               v0.AuxInt = int64(int16(c | d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpOr32(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (Or32  (Const32 [c])  (Const32 [d]))
+       // cond:
+       // result: (Const32 [int64(int32(c|d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst32 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst32)
+               v.AuxInt = int64(int32(c | d))
+               return true
+       }
        // match: (Or32 x (Const32 <t> [c]))
        // cond: x.Op != OpConst32
        // result: (Or32 (Const32 <t> [c]) x)
@@ -9300,64 +10989,137 @@ func rewriteValuegeneric_OpOr32(v *Value, config *Config) bool {
                if x != v_1.Args[0] {
                        break
                }
-               y := v_1.Args[1]
+               y := v_1.Args[1]
+               v.reset(OpOr32)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Or32 x (Or32 y x))
+       // cond:
+       // result: (Or32 x y)
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpOr32 {
+                       break
+               }
+               y := v_1.Args[0]
+               if x != v_1.Args[1] {
+                       break
+               }
+               v.reset(OpOr32)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Or32 (Or32 x y) x)
+       // cond:
+       // result: (Or32 x y)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpOr32 {
+                       break
+               }
+               x := v_0.Args[0]
+               y := v_0.Args[1]
+               if x != v.Args[1] {
+                       break
+               }
+               v.reset(OpOr32)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Or32 (Or32 x y) y)
+       // cond:
+       // result: (Or32 x y)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpOr32 {
+                       break
+               }
+               x := v_0.Args[0]
+               y := v_0.Args[1]
+               if y != v.Args[1] {
+                       break
+               }
                v.reset(OpOr32)
                v.AddArg(x)
                v.AddArg(y)
                return true
        }
-       // match: (Or32 x (Or32 y x))
-       // cond:
-       // result: (Or32 x y)
+       // match: (Or32 x l:(Or32 _ _))
+       // cond: (x.Op != OpOr32 && x.Op != OpConst32)
+       // result: (Or32 l x)
        for {
                x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpOr32 {
+               l := v.Args[1]
+               if l.Op != OpOr32 {
                        break
                }
-               y := v_1.Args[0]
-               if x != v_1.Args[1] {
+               if !(x.Op != OpOr32 && x.Op != OpConst32) {
                        break
                }
                v.reset(OpOr32)
+               v.AddArg(l)
                v.AddArg(x)
-               v.AddArg(y)
                return true
        }
-       // match: (Or32 (Or32 x y) x)
-       // cond:
-       // result: (Or32 x y)
+       // match: (Or32 (Or32 i:(Const32 <t>) z) x)
+       // cond: (z.Op != OpConst32 && x.Op != OpConst32)
+       // result: (Or32 i (Or32 <t> z x))
        for {
                v_0 := v.Args[0]
                if v_0.Op != OpOr32 {
                        break
                }
-               x := v_0.Args[0]
-               y := v_0.Args[1]
-               if x != v.Args[1] {
+               i := v_0.Args[0]
+               if i.Op != OpConst32 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst32 && x.Op != OpConst32) {
                        break
                }
                v.reset(OpOr32)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpOr32, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
                return true
        }
-       // match: (Or32 (Or32 x y) y)
+       // match: (Or32 (Const32 <t> [c]) (Or32 (Const32 <t> [d]) x))
        // cond:
-       // result: (Or32 x y)
+       // result: (Or32 (Const32 <t> [int64(int32(c|d))]) x)
        for {
                v_0 := v.Args[0]
-               if v_0.Op != OpOr32 {
+               if v_0.Op != OpConst32 {
                        break
                }
-               x := v_0.Args[0]
-               y := v_0.Args[1]
-               if y != v.Args[1] {
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpOr32 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst32 {
+                       break
+               }
+               if v_1_0.Type != t {
                        break
                }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
                v.reset(OpOr32)
+               v0 := b.NewValue0(v.Pos, OpConst32, t)
+               v0.AuxInt = int64(int32(c | d))
+               v.AddArg(v0)
                v.AddArg(x)
-               v.AddArg(y)
                return true
        }
        return false
@@ -9365,6 +11127,24 @@ func rewriteValuegeneric_OpOr32(v *Value, config *Config) bool {
 func rewriteValuegeneric_OpOr64(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (Or64  (Const64 [c])  (Const64 [d]))
+       // cond:
+       // result: (Const64 [c|d])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst64)
+               v.AuxInt = c | d
+               return true
+       }
        // match: (Or64 x (Const64 <t> [c]))
        // cond: x.Op != OpConst64
        // result: (Or64 (Const64 <t> [c]) x)
@@ -9503,11 +11283,102 @@ func rewriteValuegeneric_OpOr64(v *Value, config *Config) bool {
                v.AddArg(y)
                return true
        }
+       // match: (Or64 x l:(Or64 _ _))
+       // cond: (x.Op != OpOr64 && x.Op != OpConst64)
+       // result: (Or64 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpOr64 {
+                       break
+               }
+               if !(x.Op != OpOr64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpOr64)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Or64 (Or64 i:(Const64 <t>) z) x)
+       // cond: (z.Op != OpConst64 && x.Op != OpConst64)
+       // result: (Or64 i (Or64 <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpOr64 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst64 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpOr64)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpOr64, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Or64 (Const64 <t> [c]) (Or64 (Const64 <t> [d]) x))
+       // cond:
+       // result: (Or64 (Const64 <t> [c|d]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpOr64 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst64 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpOr64)
+               v0 := b.NewValue0(v.Pos, OpConst64, t)
+               v0.AuxInt = c | d
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpOr8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (Or8   (Const8 [c])   (Const8 [d]))
+       // cond:
+       // result: (Const8  [int64(int8(c|d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst8 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst8)
+               v.AuxInt = int64(int8(c | d))
+               return true
+       }
        // match: (Or8  x (Const8  <t> [c]))
        // cond: x.Op != OpConst8
        // result: (Or8  (Const8  <t> [c]) x)
@@ -9646,6 +11517,79 @@ func rewriteValuegeneric_OpOr8(v *Value, config *Config) bool {
                v.AddArg(y)
                return true
        }
+       // match: (Or8  x l:(Or8  _ _))
+       // cond: (x.Op != OpOr8  && x.Op != OpConst8)
+       // result: (Or8  l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpOr8 {
+                       break
+               }
+               if !(x.Op != OpOr8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpOr8)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Or8  (Or8  i:(Const8  <t>) z) x)
+       // cond: (z.Op != OpConst8  && x.Op != OpConst8)
+       // result: (Or8  i (Or8  <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpOr8 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst8 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpOr8)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpOr8, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Or8  (Const8  <t> [c]) (Or8  (Const8  <t> [d]) x))
+       // cond:
+       // result: (Or8  (Const8  <t> [int64(int8(c|d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpOr8 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst8 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpOr8)
+               v0 := b.NewValue0(v.Pos, OpConst8, t)
+               v0.AuxInt = int64(int8(c | d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpPhi(v *Value, config *Config) bool {
@@ -13068,13 +15012,125 @@ func rewriteValuegeneric_OpSub16(v *Value, config *Config) bool {
                if v_0.Op != OpAdd16 {
                        break
                }
-               x := v_0.Args[0]
-               y := v_0.Args[1]
-               if y != v.Args[1] {
+               x := v_0.Args[0]
+               y := v_0.Args[1]
+               if y != v.Args[1] {
+                       break
+               }
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (Sub16 x (Sub16 i:(Const16 <t>) z))
+       // cond: (z.Op != OpConst16 && x.Op != OpConst16)
+       // result: (Sub16 (Add16 <t> x z) i)
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub16 {
+                       break
+               }
+               i := v_1.Args[0]
+               if i.Op != OpConst16 {
+                       break
+               }
+               t := i.Type
+               z := v_1.Args[1]
+               if !(z.Op != OpConst16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpSub16)
+               v0 := b.NewValue0(v.Pos, OpAdd16, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
+               return true
+       }
+       // match: (Sub16 x (Sub16 z i:(Const16 <t>)))
+       // cond: (z.Op != OpConst16 && x.Op != OpConst16)
+       // result: (Add16 i (Sub16 <t> x z))
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub16 {
+                       break
+               }
+               z := v_1.Args[0]
+               i := v_1.Args[1]
+               if i.Op != OpConst16 {
+                       break
+               }
+               t := i.Type
+               if !(z.Op != OpConst16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpAdd16)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub16, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Sub16 (Const16 <t> [c]) (Sub16 x (Const16 <t> [d])))
+       // cond:
+       // result: (Sub16 (Const16 <t> [int64(int16(c+d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub16 {
+                       break
+               }
+               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
+               }
+               d := v_1_1.AuxInt
+               v.reset(OpSub16)
+               v0 := b.NewValue0(v.Pos, OpConst16, t)
+               v0.AuxInt = int64(int16(c + d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Sub16 (Const16 <t> [c]) (Sub16 (Const16 <t> [d]) x))
+       // cond:
+       // result: (Add16 (Const16 <t> [int64(int16(c-d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub16 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst16 {
+                       break
+               }
+               if v_1_0.Type != t {
                        break
                }
-               v.reset(OpCopy)
-               v.Type = x.Type
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpAdd16)
+               v0 := b.NewValue0(v.Pos, OpConst16, t)
+               v0.AuxInt = int64(int16(c - d))
+               v.AddArg(v0)
                v.AddArg(x)
                return true
        }
@@ -13170,6 +15226,118 @@ func rewriteValuegeneric_OpSub32(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
+       // match: (Sub32 x (Sub32 i:(Const32 <t>) z))
+       // cond: (z.Op != OpConst32 && x.Op != OpConst32)
+       // result: (Sub32 (Add32 <t> x z) i)
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub32 {
+                       break
+               }
+               i := v_1.Args[0]
+               if i.Op != OpConst32 {
+                       break
+               }
+               t := i.Type
+               z := v_1.Args[1]
+               if !(z.Op != OpConst32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpSub32)
+               v0 := b.NewValue0(v.Pos, OpAdd32, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
+               return true
+       }
+       // match: (Sub32 x (Sub32 z i:(Const32 <t>)))
+       // cond: (z.Op != OpConst32 && x.Op != OpConst32)
+       // result: (Add32 i (Sub32 <t> x z))
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub32 {
+                       break
+               }
+               z := v_1.Args[0]
+               i := v_1.Args[1]
+               if i.Op != OpConst32 {
+                       break
+               }
+               t := i.Type
+               if !(z.Op != OpConst32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpAdd32)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub32, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Sub32 (Const32 <t> [c]) (Sub32 x (Const32 <t> [d])))
+       // cond:
+       // result: (Sub32 (Const32 <t> [int64(int32(c+d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub32 {
+                       break
+               }
+               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
+               }
+               d := v_1_1.AuxInt
+               v.reset(OpSub32)
+               v0 := b.NewValue0(v.Pos, OpConst32, t)
+               v0.AuxInt = int64(int32(c + d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Sub32 (Const32 <t> [c]) (Sub32 (Const32 <t> [d]) x))
+       // cond:
+       // result: (Add32 (Const32 <t> [int64(int32(c-d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub32 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst32 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpAdd32)
+               v0 := b.NewValue0(v.Pos, OpConst32, t)
+               v0.AuxInt = int64(int32(c - d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpSub32F(v *Value, config *Config) bool {
@@ -13302,6 +15470,118 @@ func rewriteValuegeneric_OpSub64(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
+       // match: (Sub64 x (Sub64 i:(Const64 <t>) z))
+       // cond: (z.Op != OpConst64 && x.Op != OpConst64)
+       // result: (Sub64 (Add64 <t> x z) i)
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub64 {
+                       break
+               }
+               i := v_1.Args[0]
+               if i.Op != OpConst64 {
+                       break
+               }
+               t := i.Type
+               z := v_1.Args[1]
+               if !(z.Op != OpConst64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpSub64)
+               v0 := b.NewValue0(v.Pos, OpAdd64, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
+               return true
+       }
+       // match: (Sub64 x (Sub64 z i:(Const64 <t>)))
+       // cond: (z.Op != OpConst64 && x.Op != OpConst64)
+       // result: (Add64 i (Sub64 <t> x z))
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub64 {
+                       break
+               }
+               z := v_1.Args[0]
+               i := v_1.Args[1]
+               if i.Op != OpConst64 {
+                       break
+               }
+               t := i.Type
+               if !(z.Op != OpConst64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpAdd64)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub64, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Sub64 (Const64 <t> [c]) (Sub64 x (Const64 <t> [d])))
+       // cond:
+       // result: (Sub64 (Const64 <t> [c+d]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub64 {
+                       break
+               }
+               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
+               }
+               d := v_1_1.AuxInt
+               v.reset(OpSub64)
+               v0 := b.NewValue0(v.Pos, OpConst64, t)
+               v0.AuxInt = c + d
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Sub64 (Const64 <t> [c]) (Sub64 (Const64 <t> [d]) x))
+       // cond:
+       // result: (Add64 (Const64 <t> [c-d]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub64 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst64 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpAdd64)
+               v0 := b.NewValue0(v.Pos, OpConst64, t)
+               v0.AuxInt = c - d
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpSub64F(v *Value, config *Config) bool {
@@ -13434,6 +15714,118 @@ func rewriteValuegeneric_OpSub8(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
+       // match: (Sub8  x (Sub8  i:(Const8  <t>) z))
+       // cond: (z.Op != OpConst8  && x.Op != OpConst8)
+       // result: (Sub8  (Add8  <t> x z) i)
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub8 {
+                       break
+               }
+               i := v_1.Args[0]
+               if i.Op != OpConst8 {
+                       break
+               }
+               t := i.Type
+               z := v_1.Args[1]
+               if !(z.Op != OpConst8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpSub8)
+               v0 := b.NewValue0(v.Pos, OpAdd8, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               v.AddArg(i)
+               return true
+       }
+       // match: (Sub8  x (Sub8  z i:(Const8  <t>)))
+       // cond: (z.Op != OpConst8  && x.Op != OpConst8)
+       // result: (Add8  i (Sub8  <t> x z))
+       for {
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub8 {
+                       break
+               }
+               z := v_1.Args[0]
+               i := v_1.Args[1]
+               if i.Op != OpConst8 {
+                       break
+               }
+               t := i.Type
+               if !(z.Op != OpConst8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpAdd8)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpSub8, t)
+               v0.AddArg(x)
+               v0.AddArg(z)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Sub8  (Const8  <t> [c]) (Sub8  x (Const8  <t> [d])))
+       // cond:
+       // result: (Sub8  (Const8  <t> [int64(int8(c+d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub8 {
+                       break
+               }
+               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
+               }
+               d := v_1_1.AuxInt
+               v.reset(OpSub8)
+               v0 := b.NewValue0(v.Pos, OpConst8, t)
+               v0.AuxInt = int64(int8(c + d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Sub8  (Const8  <t> [c]) (Sub8  (Const8  <t> [d]) x))
+       // cond:
+       // result: (Add8  (Const8  <t> [int64(int8(c-d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpSub8 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst8 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpAdd8)
+               v0 := b.NewValue0(v.Pos, OpConst8, t)
+               v0.AuxInt = int64(int8(c - d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpTrunc16to8(v *Value, config *Config) bool {
@@ -13945,6 +16337,24 @@ func rewriteValuegeneric_OpTrunc64to8(v *Value, config *Config) bool {
 func rewriteValuegeneric_OpXor16(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (Xor16  (Const16 [c])  (Const16 [d]))
+       // cond:
+       // result: (Const16 [int64(int16(c^d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst16 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst16)
+               v.AuxInt = int64(int16(c ^ d))
+               return true
+       }
        // match: (Xor16 x (Const16 <t> [c]))
        // cond: x.Op != OpConst16
        // result: (Xor16 (Const16 <t> [c]) x)
@@ -14067,11 +16477,102 @@ func rewriteValuegeneric_OpXor16(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
+       // match: (Xor16 x l:(Xor16 _ _))
+       // cond: (x.Op != OpXor16 && x.Op != OpConst16)
+       // result: (Xor16 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpXor16 {
+                       break
+               }
+               if !(x.Op != OpXor16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpXor16)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Xor16 (Xor16 i:(Const16 <t>) z) x)
+       // cond: (z.Op != OpConst16 && x.Op != OpConst16)
+       // result: (Xor16 i (Xor16 <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpXor16 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst16 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst16 && x.Op != OpConst16) {
+                       break
+               }
+               v.reset(OpXor16)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpXor16, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Xor16 (Const16 <t> [c]) (Xor16 (Const16 <t> [d]) x))
+       // cond:
+       // result: (Xor16 (Const16 <t> [int64(int16(c^d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst16 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpXor16 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst16 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpXor16)
+               v0 := b.NewValue0(v.Pos, OpConst16, t)
+               v0.AuxInt = int64(int16(c ^ d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpXor32(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (Xor32  (Const32 [c])  (Const32 [d]))
+       // cond:
+       // result: (Const32 [int64(int32(c^d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst32 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst32)
+               v.AuxInt = int64(int32(c ^ d))
+               return true
+       }
        // match: (Xor32 x (Const32 <t> [c]))
        // cond: x.Op != OpConst32
        // result: (Xor32 (Const32 <t> [c]) x)
@@ -14194,11 +16695,102 @@ func rewriteValuegeneric_OpXor32(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
+       // match: (Xor32 x l:(Xor32 _ _))
+       // cond: (x.Op != OpXor32 && x.Op != OpConst32)
+       // result: (Xor32 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpXor32 {
+                       break
+               }
+               if !(x.Op != OpXor32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpXor32)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Xor32 (Xor32 i:(Const32 <t>) z) x)
+       // cond: (z.Op != OpConst32 && x.Op != OpConst32)
+       // result: (Xor32 i (Xor32 <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpXor32 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst32 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst32 && x.Op != OpConst32) {
+                       break
+               }
+               v.reset(OpXor32)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpXor32, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Xor32 (Const32 <t> [c]) (Xor32 (Const32 <t> [d]) x))
+       // cond:
+       // result: (Xor32 (Const32 <t> [int64(int32(c^d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst32 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpXor32 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst32 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpXor32)
+               v0 := b.NewValue0(v.Pos, OpConst32, t)
+               v0.AuxInt = int64(int32(c ^ d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpXor64(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (Xor64  (Const64 [c])  (Const64 [d]))
+       // cond:
+       // result: (Const64 [c^d])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst64 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst64)
+               v.AuxInt = c ^ d
+               return true
+       }
        // match: (Xor64 x (Const64 <t> [c]))
        // cond: x.Op != OpConst64
        // result: (Xor64 (Const64 <t> [c]) x)
@@ -14321,11 +16913,102 @@ func rewriteValuegeneric_OpXor64(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
+       // match: (Xor64 x l:(Xor64 _ _))
+       // cond: (x.Op != OpXor64 && x.Op != OpConst64)
+       // result: (Xor64 l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpXor64 {
+                       break
+               }
+               if !(x.Op != OpXor64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpXor64)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Xor64 (Xor64 i:(Const64 <t>) z) x)
+       // cond: (z.Op != OpConst64 && x.Op != OpConst64)
+       // result: (Xor64 i (Xor64 <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpXor64 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst64 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst64 && x.Op != OpConst64) {
+                       break
+               }
+               v.reset(OpXor64)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpXor64, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Xor64 (Const64 <t> [c]) (Xor64 (Const64 <t> [d]) x))
+       // cond:
+       // result: (Xor64 (Const64 <t> [c^d]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst64 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpXor64 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst64 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpXor64)
+               v0 := b.NewValue0(v.Pos, OpConst64, t)
+               v0.AuxInt = c ^ d
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpXor8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (Xor8   (Const8 [c])   (Const8 [d]))
+       // cond:
+       // result: (Const8  [int64(int8(c^d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpConst8 {
+                       break
+               }
+               d := v_1.AuxInt
+               v.reset(OpConst8)
+               v.AuxInt = int64(int8(c ^ d))
+               return true
+       }
        // match: (Xor8  x (Const8  <t> [c]))
        // cond: x.Op != OpConst8
        // result: (Xor8  (Const8  <t> [c]) x)
@@ -14448,6 +17131,79 @@ func rewriteValuegeneric_OpXor8(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
+       // match: (Xor8  x l:(Xor8  _ _))
+       // cond: (x.Op != OpXor8  && x.Op != OpConst8)
+       // result: (Xor8  l x)
+       for {
+               x := v.Args[0]
+               l := v.Args[1]
+               if l.Op != OpXor8 {
+                       break
+               }
+               if !(x.Op != OpXor8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpXor8)
+               v.AddArg(l)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Xor8  (Xor8  i:(Const8  <t>) z) x)
+       // cond: (z.Op != OpConst8  && x.Op != OpConst8)
+       // result: (Xor8  i (Xor8  <t> z x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpXor8 {
+                       break
+               }
+               i := v_0.Args[0]
+               if i.Op != OpConst8 {
+                       break
+               }
+               t := i.Type
+               z := v_0.Args[1]
+               x := v.Args[1]
+               if !(z.Op != OpConst8 && x.Op != OpConst8) {
+                       break
+               }
+               v.reset(OpXor8)
+               v.AddArg(i)
+               v0 := b.NewValue0(v.Pos, OpXor8, t)
+               v0.AddArg(z)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (Xor8  (Const8  <t> [c]) (Xor8  (Const8  <t> [d]) x))
+       // cond:
+       // result: (Xor8  (Const8  <t> [int64(int8(c^d))]) x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpConst8 {
+                       break
+               }
+               t := v_0.Type
+               c := v_0.AuxInt
+               v_1 := v.Args[1]
+               if v_1.Op != OpXor8 {
+                       break
+               }
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpConst8 {
+                       break
+               }
+               if v_1_0.Type != t {
+                       break
+               }
+               d := v_1_0.AuxInt
+               x := v_1.Args[1]
+               v.reset(OpXor8)
+               v0 := b.NewValue0(v.Pos, OpConst8, t)
+               v0.AuxInt = int64(int8(c ^ d))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpZero(v *Value, config *Config) bool {
index ea195217e685b2428a293bd882a874a0cd13977f..010f11f027386f1d29113451ad1ea298445d78dd 100644 (file)
@@ -197,7 +197,7 @@ func k4(a [100]int) [100]int {
 func k5(a [100]int) [100]int {
        max := (1 << 63) - 1
        for i := max - 50; i < max; i++ { // ERROR "Induction variable with minimum 9223372036854775757 and increment 1$"
-               a[i-max+50] = i
+               a[i-max+50] = i   // ERROR "Found redundant \(IsInBounds ind 100\), ind < 50$"
                a[i-(max-70)] = i // ERROR "Found redundant \(IsInBounds ind 100\), ind < 70$"
        }
        return a