From: philhofer Date: Mon, 20 Feb 2017 16:43:54 +0000 (-0800) Subject: cmd/compile/ssa: more aggressive constant folding X-Git-Tag: go1.9beta1~1394 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=379567aad19e97eb2145d7bbe45a7a2febccd3e4;p=gostls13.git cmd/compile/ssa: more aggressive constant folding 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 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index f485f43875..740ba8606a 100644 --- a/src/cmd/compile/internal/ssa/gen/generic.rules +++ b/src/cmd/compile/internal/ssa/gen/generic.rules @@ -115,6 +115,21 @@ (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))]) @@ -602,6 +617,10 @@ (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) @@ -1201,6 +1220,148 @@ (Mod64u x (Const64 [c])) && x.Op != OpConst64 && c > 0 && umagicOK(64,c) -> (Sub64 x (Mul64 (Div64u x (Const64 [c])) (Const64 [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 ) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Add64 i (Add64 z x)) +(Add32 (Add32 i:(Const32 ) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Add32 i (Add32 z x)) +(Add16 (Add16 i:(Const16 ) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Add16 i (Add16 z x)) +(Add8 (Add8 i:(Const8 ) z) x) && (z.Op != OpConst8 && x.Op != OpConst8) -> (Add8 i (Add8 z x)) + +// x + (C - z) -> C + (x - z) +(Add64 (Sub64 i:(Const64 ) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Add64 i (Sub64 x z)) +(Add32 (Sub32 i:(Const32 ) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Add32 i (Sub32 x z)) +(Add16 (Sub16 i:(Const16 ) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Add16 i (Sub16 x z)) +(Add8 (Sub8 i:(Const8 ) z) x) && (z.Op != OpConst8 && x.Op != OpConst8) -> (Add8 i (Sub8 x z)) +(Add64 x (Sub64 i:(Const64 ) z)) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Add64 i (Sub64 x z)) +(Add32 x (Sub32 i:(Const32 ) z)) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Add32 i (Sub32 x z)) +(Add16 x (Sub16 i:(Const16 ) z)) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Add16 i (Sub16 x z)) +(Add8 x (Sub8 i:(Const8 ) z)) && (z.Op != OpConst8 && x.Op != OpConst8) -> (Add8 i (Sub8 x z)) + +// x + (z - C) -> (x + z) - C +(Add64 (Sub64 z i:(Const64 )) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Sub64 (Add64 x z) i) +(Add32 (Sub32 z i:(Const32 )) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Sub32 (Add32 x z) i) +(Add16 (Sub16 z i:(Const16 )) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Sub16 (Add16 x z) i) +(Add8 (Sub8 z i:(Const8 )) x) && (z.Op != OpConst8 && x.Op != OpConst8) -> (Sub8 (Add8 x z) i) +(Add64 x (Sub64 z i:(Const64 ))) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Sub64 (Add64 x z) i) +(Add32 x (Sub32 z i:(Const32 ))) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Sub32 (Add32 x z) i) +(Add16 x (Sub16 z i:(Const16 ))) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Sub16 (Add16 x z) i) +(Add8 x (Sub8 z i:(Const8 ))) && (z.Op != OpConst8 && x.Op != OpConst8) -> (Sub8 (Add8 x z) i) + +// x - (C - z) -> x + (z - C) -> (x + z) - C +(Sub64 x (Sub64 i:(Const64 ) z)) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Sub64 (Add64 x z) i) +(Sub32 x (Sub32 i:(Const32 ) z)) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Sub32 (Add32 x z) i) +(Sub16 x (Sub16 i:(Const16 ) z)) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Sub16 (Add16 x z) i) +(Sub8 x (Sub8 i:(Const8 ) z)) && (z.Op != OpConst8 && x.Op != OpConst8) -> (Sub8 (Add8 x z) i) + +// x - (z - C) -> x + (C - z) -> (x - z) + C +(Sub64 x (Sub64 z i:(Const64 ))) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Add64 i (Sub64 x z)) +(Sub32 x (Sub32 z i:(Const32 ))) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Add32 i (Sub32 x z)) +(Sub16 x (Sub16 z i:(Const16 ))) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Add16 i (Sub16 x z)) +(Sub8 x (Sub8 z i:(Const8 ))) && (z.Op != OpConst8 && x.Op != OpConst8) -> (Add8 i (Sub8 x z)) + +// x & (C & z) -> C & (x & z) +(And64 (And64 i:(Const64 ) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (And64 i (And64 z x)) +(And32 (And32 i:(Const32 ) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (And32 i (And32 z x)) +(And16 (And16 i:(Const16 ) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (And16 i (And16 z x)) +(And8 (And8 i:(Const8 ) z) x) && (z.Op != OpConst8 && x.Op != OpConst8) -> (And8 i (And8 z x)) + +// x | (C | z) -> C | (x | z) +(Or64 (Or64 i:(Const64 ) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Or64 i (Or64 z x)) +(Or32 (Or32 i:(Const32 ) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Or32 i (Or32 z x)) +(Or16 (Or16 i:(Const16 ) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Or16 i (Or16 z x)) +(Or8 (Or8 i:(Const8 ) z) x) && (z.Op != OpConst8 && x.Op != OpConst8) -> (Or8 i (Or8 z x)) + +// x ^ (C ^ z) -> C ^ (x ^ z) +(Xor64 (Xor64 i:(Const64 ) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) -> (Xor64 i (Xor64 z x)) +(Xor32 (Xor32 i:(Const32 ) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) -> (Xor32 i (Xor32 z x)) +(Xor16 (Xor16 i:(Const16 ) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) -> (Xor16 i (Xor16 z x)) +(Xor8 (Xor8 i:(Const8 ) z) x) && (z.Op != OpConst8 && x.Op != OpConst8) -> (Xor8 i (Xor8 z x)) + +// C + (D + x) -> (C + D) + x +(Add64 (Const64 [c]) (Add64 (Const64 [d]) x)) -> (Add64 (Const64 [c+d]) x) +(Add32 (Const32 [c]) (Add32 (Const32 [d]) x)) -> (Add32 (Const32 [int64(int32(c+d))]) x) +(Add16 (Const16 [c]) (Add16 (Const16 [d]) x)) -> (Add16 (Const16 [int64(int16(c+d))]) x) +(Add8 (Const8 [c]) (Add8 (Const8 [d]) x)) -> (Add8 (Const8 [int64(int8(c+d))]) x) + +// C + (D - x) -> (C + D) - x +(Add64 (Const64 [c]) (Sub64 (Const64 [d]) x)) -> (Sub64 (Const64 [c+d]) x) +(Add32 (Const32 [c]) (Sub32 (Const32 [d]) x)) -> (Sub32 (Const32 [int64(int32(c+d))]) x) +(Add16 (Const16 [c]) (Sub16 (Const16 [d]) x)) -> (Sub16 (Const16 [int64(int16(c+d))]) x) +(Add8 (Const8 [c]) (Sub8 (Const8 [d]) x)) -> (Sub8 (Const8 [int64(int8(c+d))]) x) + +// C + (x - D) -> (C - D) + x +(Add64 (Const64 [c]) (Sub64 x (Const64 [d]))) -> (Add64 (Const64 [c-d]) x) +(Add32 (Const32 [c]) (Sub32 x (Const32 [d]))) -> (Add32 (Const32 [int64(int32(c-d))]) x) +(Add16 (Const16 [c]) (Sub16 x (Const16 [d]))) -> (Add16 (Const16 [int64(int16(c-d))]) x) +(Add8 (Const8 [c]) (Sub8 x (Const8 [d]))) -> (Add8 (Const8 [int64(int8(c-d))]) x) + +// C - (x - D) -> (C + D) - x +(Sub64 (Const64 [c]) (Sub64 x (Const64 [d]))) -> (Sub64 (Const64 [c+d]) x) +(Sub32 (Const32 [c]) (Sub32 x (Const32 [d]))) -> (Sub32 (Const32 [int64(int32(c+d))]) x) +(Sub16 (Const16 [c]) (Sub16 x (Const16 [d]))) -> (Sub16 (Const16 [int64(int16(c+d))]) x) +(Sub8 (Const8 [c]) (Sub8 x (Const8 [d]))) -> (Sub8 (Const8 [int64(int8(c+d))]) x) + +// C - (D - x) -> (C - D) + x +(Sub64 (Const64 [c]) (Sub64 (Const64 [d]) x)) -> (Add64 (Const64 [c-d]) x) +(Sub32 (Const32 [c]) (Sub32 (Const32 [d]) x)) -> (Add32 (Const32 [int64(int32(c-d))]) x) +(Sub16 (Const16 [c]) (Sub16 (Const16 [d]) x)) -> (Add16 (Const16 [int64(int16(c-d))]) x) +(Sub8 (Const8 [c]) (Sub8 (Const8 [d]) x)) -> (Add8 (Const8 [int64(int8(c-d))]) x) + +// C & (D & x) -> (C & D) & x +(And64 (Const64 [c]) (And64 (Const64 [d]) x)) -> (And64 (Const64 [c&d]) x) +(And32 (Const32 [c]) (And32 (Const32 [d]) x)) -> (And32 (Const32 [int64(int32(c&d))]) x) +(And16 (Const16 [c]) (And16 (Const16 [d]) x)) -> (And16 (Const16 [int64(int16(c&d))]) x) +(And8 (Const8 [c]) (And8 (Const8 [d]) x)) -> (And8 (Const8 [int64(int8(c&d))]) x) + +// C | (D | x) -> (C | D) | x +(Or64 (Const64 [c]) (Or64 (Const64 [d]) x)) -> (Or64 (Const64 [c|d]) x) +(Or32 (Const32 [c]) (Or32 (Const32 [d]) x)) -> (Or32 (Const32 [int64(int32(c|d))]) x) +(Or16 (Const16 [c]) (Or16 (Const16 [d]) x)) -> (Or16 (Const16 [int64(int16(c|d))]) x) +(Or8 (Const8 [c]) (Or8 (Const8 [d]) x)) -> (Or8 (Const8 [int64(int8(c|d))]) x) + +// C ^ (D ^ x) -> (C ^ D) ^ x +(Xor64 (Const64 [c]) (Xor64 (Const64 [d]) x)) -> (Xor64 (Const64 [c^d]) x) +(Xor32 (Const32 [c]) (Xor32 (Const32 [d]) x)) -> (Xor32 (Const32 [int64(int32(c^d))]) x) +(Xor16 (Const16 [c]) (Xor16 (Const16 [d]) x)) -> (Xor16 (Const16 [int64(int16(c^d))]) x) +(Xor8 (Const8 [c]) (Xor8 (Const8 [d]) x)) -> (Xor8 (Const8 [int64(int8(c^d))]) x) + +// C * (D * x) = (C * D) * x +(Mul64 (Const64 [c]) (Mul64 (Const64 [d]) x)) -> (Mul64 (Const64 [c*d]) x) +(Mul32 (Const32 [c]) (Mul32 (Const32 [d]) x)) -> (Mul32 (Const32 [int64(int32(c*d))]) x) +(Mul16 (Const16 [c]) (Mul16 (Const16 [d]) x)) -> (Mul16 (Const16 [int64(int16(c*d))]) x) +(Mul8 (Const8 [c]) (Mul8 (Const8 [d]) x)) -> (Mul8 (Const8 [int64(int8(c*d))]) x) + // floating point optimizations (Add32F x (Const32F [0])) -> x (Add32F (Const32F [0]) x) -> x diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index 3033a31f98..f17bf3343c 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -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 ) z) x) + // cond: (z.Op != OpConst16 && x.Op != OpConst16) + // result: (Add16 i (Add16 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 ) z) x) + // cond: (z.Op != OpConst16 && x.Op != OpConst16) + // result: (Add16 i (Sub16 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 ) z)) + // cond: (z.Op != OpConst16 && x.Op != OpConst16) + // result: (Add16 i (Sub16 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 )) x) + // cond: (z.Op != OpConst16 && x.Op != OpConst16) + // result: (Sub16 (Add16 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 ))) + // cond: (z.Op != OpConst16 && x.Op != OpConst16) + // result: (Sub16 (Add16 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 [c]) (Add16 (Const16 [d]) x)) + // cond: + // result: (Add16 (Const16 [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 [c]) (Sub16 (Const16 [d]) x)) + // cond: + // result: (Sub16 (Const16 [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 [c]) (Sub16 x (Const16 [d]))) + // cond: + // result: (Add16 (Const16 [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 ) z) x) + // cond: (z.Op != OpConst32 && x.Op != OpConst32) + // result: (Add32 i (Add32 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 ) z) x) + // cond: (z.Op != OpConst32 && x.Op != OpConst32) + // result: (Add32 i (Sub32 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 ) z)) + // cond: (z.Op != OpConst32 && x.Op != OpConst32) + // result: (Add32 i (Sub32 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 )) x) + // cond: (z.Op != OpConst32 && x.Op != OpConst32) + // result: (Sub32 (Add32 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 ))) + // cond: (z.Op != OpConst32 && x.Op != OpConst32) + // result: (Sub32 (Add32 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 [c]) (Add32 (Const32 [d]) x)) + // cond: + // result: (Add32 (Const32 [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 [c]) (Sub32 (Const32 [d]) x)) + // cond: + // result: (Sub32 (Const32 [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 [c]) (Sub32 x (Const32 [d]))) + // cond: + // result: (Add32 (Const32 [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 [c])) + // cond: x.Op != OpConst64 + // result: (Add64 (Const64 [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 ) z) x) + // cond: (z.Op != OpConst64 && x.Op != OpConst64) + // result: (Add64 i (Add64 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 ) z) x) + // cond: (z.Op != OpConst64 && x.Op != OpConst64) + // result: (Add64 i (Sub64 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 ) z)) + // cond: (z.Op != OpConst64 && x.Op != OpConst64) + // result: (Add64 i (Sub64 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 )) x) + // cond: (z.Op != OpConst64 && x.Op != OpConst64) + // result: (Sub64 (Add64 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 ))) + // cond: (z.Op != OpConst64 && x.Op != OpConst64) + // result: (Sub64 (Add64 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 [c]) (Add64 (Const64 [d]) x)) + // cond: + // result: (Add64 (Const64 [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 [c]) (Sub64 (Const64 [d]) x)) + // cond: + // result: (Sub64 (Const64 [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 [c]) (Sub64 x (Const64 [d]))) + // cond: + // result: (Add64 (Const64 [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 [c])) + // cond: x.Op != OpConst8 + // result: (Add8 (Const8 [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 ) z) x) + // cond: (z.Op != OpConst8 && x.Op != OpConst8) + // result: (Add8 i (Add8 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 ) z) x) + // cond: (z.Op != OpConst8 && x.Op != OpConst8) + // result: (Add8 i (Sub8 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 [c])) - // cond: x.Op != OpConst64 - // result: (Add64 (Const64 [c]) x) + // match: (Add8 x (Sub8 i:(Const8 ) z)) + // cond: (z.Op != OpConst8 && x.Op != OpConst8) + // result: (Add8 i (Sub8 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 )) x) + // cond: (z.Op != OpConst8 && x.Op != OpConst8) + // result: (Sub8 (Add8 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 ))) + // cond: (z.Op != OpConst8 && x.Op != OpConst8) + // result: (Sub8 (Add8 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 [c]) (Add8 (Const8 [d]) x)) // cond: - // result: x + // result: (Add8 (Const8 [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 [c]) (Sub8 (Const8 [d]) x)) // cond: - // result: (Const8 [int64(int8(c+d))]) + // result: (Sub8 (Const8 [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 [c])) - // cond: x.Op != OpConst8 - // result: (Add8 (Const8 [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 [c]) (Sub8 x (Const8 [d]))) // cond: - // result: x + // result: (Add8 (Const8 [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 [c])) // cond: x.Op != OpConst16 // result: (And16 (Const16 [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 ) z) x) + // cond: (z.Op != OpConst16 && x.Op != OpConst16) + // result: (And16 i (And16 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 [c]) (And16 (Const16 [d]) x)) + // cond: + // result: (And16 (Const16 [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 [c])) // cond: x.Op != OpConst32 // result: (And32 (Const32 [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 ) z) x) + // cond: (z.Op != OpConst32 && x.Op != OpConst32) + // result: (And32 i (And32 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 [c]) (And32 (Const32 [d]) x)) + // cond: + // result: (And32 (Const32 [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 [c])) // cond: x.Op != OpConst64 // result: (And64 (Const64 [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 ) z) x) + // cond: (z.Op != OpConst64 && x.Op != OpConst64) + // result: (And64 i (And64 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 [c]) (And64 (Const64 [d]) x)) + // cond: + // result: (And64 (Const64 [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 [c])) // cond: x.Op != OpConst8 // result: (And8 (Const8 [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 ) z) x) + // cond: (z.Op != OpConst8 && x.Op != OpConst8) + // result: (And8 i (And8 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 [c]) (And8 (Const8 [d]) x)) + // cond: + // result: (And8 (Const8 [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 [c]) (Mul16 (Const16 [d]) x)) + // cond: + // result: (Mul16 (Const16 [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 [c]) (Mul32 (Const32 [d]) x)) + // cond: + // result: (Mul32 (Const32 [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 [c]) (Mul64 (Const64 [d]) x)) + // cond: + // result: (Mul64 (Const64 [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 [c]) (Mul8 (Const8 [d]) x)) + // cond: + // result: (Mul8 (Const8 [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 [c])) // cond: x.Op != OpConst16 // result: (Or16 (Const16 [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 ) z) x) + // cond: (z.Op != OpConst16 && x.Op != OpConst16) + // result: (Or16 i (Or16 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 [c]) (Or16 (Const16 [d]) x)) + // cond: + // result: (Or16 (Const16 [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 [c])) // cond: x.Op != OpConst32 // result: (Or32 (Const32 [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 ) z) x) + // cond: (z.Op != OpConst32 && x.Op != OpConst32) + // result: (Or32 i (Or32 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 [c]) (Or32 (Const32 [d]) x)) // cond: - // result: (Or32 x y) + // result: (Or32 (Const32 [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 [c])) // cond: x.Op != OpConst64 // result: (Or64 (Const64 [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 ) z) x) + // cond: (z.Op != OpConst64 && x.Op != OpConst64) + // result: (Or64 i (Or64 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 [c]) (Or64 (Const64 [d]) x)) + // cond: + // result: (Or64 (Const64 [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 [c])) // cond: x.Op != OpConst8 // result: (Or8 (Const8 [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 ) z) x) + // cond: (z.Op != OpConst8 && x.Op != OpConst8) + // result: (Or8 i (Or8 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 [c]) (Or8 (Const8 [d]) x)) + // cond: + // result: (Or8 (Const8 [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 ) z)) + // cond: (z.Op != OpConst16 && x.Op != OpConst16) + // result: (Sub16 (Add16 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 ))) + // cond: (z.Op != OpConst16 && x.Op != OpConst16) + // result: (Add16 i (Sub16 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 [c]) (Sub16 x (Const16 [d]))) + // cond: + // result: (Sub16 (Const16 [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 [c]) (Sub16 (Const16 [d]) x)) + // cond: + // result: (Add16 (Const16 [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 ) z)) + // cond: (z.Op != OpConst32 && x.Op != OpConst32) + // result: (Sub32 (Add32 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 ))) + // cond: (z.Op != OpConst32 && x.Op != OpConst32) + // result: (Add32 i (Sub32 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 [c]) (Sub32 x (Const32 [d]))) + // cond: + // result: (Sub32 (Const32 [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 [c]) (Sub32 (Const32 [d]) x)) + // cond: + // result: (Add32 (Const32 [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 ) z)) + // cond: (z.Op != OpConst64 && x.Op != OpConst64) + // result: (Sub64 (Add64 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 ))) + // cond: (z.Op != OpConst64 && x.Op != OpConst64) + // result: (Add64 i (Sub64 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 [c]) (Sub64 x (Const64 [d]))) + // cond: + // result: (Sub64 (Const64 [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 [c]) (Sub64 (Const64 [d]) x)) + // cond: + // result: (Add64 (Const64 [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 ) z)) + // cond: (z.Op != OpConst8 && x.Op != OpConst8) + // result: (Sub8 (Add8 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 ))) + // cond: (z.Op != OpConst8 && x.Op != OpConst8) + // result: (Add8 i (Sub8 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 [c]) (Sub8 x (Const8 [d]))) + // cond: + // result: (Sub8 (Const8 [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 [c]) (Sub8 (Const8 [d]) x)) + // cond: + // result: (Add8 (Const8 [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 [c])) // cond: x.Op != OpConst16 // result: (Xor16 (Const16 [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 ) z) x) + // cond: (z.Op != OpConst16 && x.Op != OpConst16) + // result: (Xor16 i (Xor16 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 [c]) (Xor16 (Const16 [d]) x)) + // cond: + // result: (Xor16 (Const16 [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 [c])) // cond: x.Op != OpConst32 // result: (Xor32 (Const32 [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 ) z) x) + // cond: (z.Op != OpConst32 && x.Op != OpConst32) + // result: (Xor32 i (Xor32 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 [c]) (Xor32 (Const32 [d]) x)) + // cond: + // result: (Xor32 (Const32 [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 [c])) // cond: x.Op != OpConst64 // result: (Xor64 (Const64 [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 ) z) x) + // cond: (z.Op != OpConst64 && x.Op != OpConst64) + // result: (Xor64 i (Xor64 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 [c]) (Xor64 (Const64 [d]) x)) + // cond: + // result: (Xor64 (Const64 [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 [c])) // cond: x.Op != OpConst8 // result: (Xor8 (Const8 [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 ) z) x) + // cond: (z.Op != OpConst8 && x.Op != OpConst8) + // result: (Xor8 i (Xor8 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 [c]) (Xor8 (Const8 [d]) x)) + // cond: + // result: (Xor8 (Const8 [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 { diff --git a/test/loopbce.go b/test/loopbce.go index ea195217e6..010f11f027 100644 --- a/test/loopbce.go +++ b/test/loopbce.go @@ -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