diff options
| author | Yi Yang <y1yang0x@gmail.com> | 2023-03-19 07:24:04 +0000 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-03-20 15:42:09 +0000 |
| commit | da4687923b8c2d42c23f61fa3db9f4d3ce0c5f54 (patch) | |
| tree | 1ef4b8154e95c82e6150b25cb9abaa256a32652e /src | |
| parent | b414ba4c993e38b0c5241f9d36021423afeb05ed (diff) | |
| download | go-da4687923b8c2d42c23f61fa3db9f4d3ce0c5f54.tar.xz | |
cmd/compile: add rewrite rules for arithmetic operations
Add the following common local transformations
(t + x) - (t + y) == x - y
(t + x) - (y + t) == x - y
(x + t) - (y + t) == x - y
(x + t) - (t + y) == x - y
(x - t) + (t + y) == x + y
(x - t) + (y + t) == x + y
The compiler itself matches such patterns many times. This also aligns with other popular compilers.
Fixes #59111
Change-Id: Ibdfdb414782f8fcaa20b84ac5d43d0d9ae2c7b60
GitHub-Last-Rev: 1aad82e62e61e89789932c2070851a023f130dd8
GitHub-Pull-Request: golang/go#59119
Reviewed-on: https://go-review.googlesource.com/c/go/+/477555
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/ssa/_gen/generic.rules | 10 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/rewritegeneric.go | 228 |
2 files changed, 238 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/generic.rules b/src/cmd/compile/internal/ssa/_gen/generic.rules index 6ede0fb200..98aedb5cde 100644 --- a/src/cmd/compile/internal/ssa/_gen/generic.rules +++ b/src/cmd/compile/internal/ssa/_gen/generic.rules @@ -573,6 +573,16 @@ (Sub(64|32|16|8) (Com(64|32|16|8) x) (Neg(64|32|16|8) x)) => (Const(64|32|16|8) [-1]) (Add(64|32|16|8) (Com(64|32|16|8) x) x) => (Const(64|32|16|8) [-1]) +// Simplification when involving common integer +// (t + x) - (t + y) == x - y +// (t + x) - (y + t) == x - y +// (x + t) - (y + t) == x - y +// (x + t) - (t + y) == x - y +// (x - t) + (t + y) == x + y +// (x - t) + (y + t) == x + y +(Sub(64|32|16|8) (Add(64|32|16|8) t x) (Add(64|32|16|8) t y)) => (Sub(64|32|16|8) x y) +(Add(64|32|16|8) (Sub(64|32|16|8) x t) (Add(64|32|16|8) t y)) => (Add(64|32|16|8) x y) + // ^(x-1) == ^x+1 == -x (Add(64|32|16|8) (Const(64|32|16|8) [1]) (Com(64|32|16|8) x)) => (Neg(64|32|16|8) x) (Com(64|32|16|8) (Add(64|32|16|8) (Const(64|32|16|8) [-1]) x)) => (Neg(64|32|16|8) x) diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index ceb52fa5fd..7baa384353 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -560,6 +560,33 @@ func rewriteValuegeneric_OpAdd16(v *Value) bool { } break } + // match: (Add16 (Sub16 x t) (Add16 t y)) + // result: (Add16 x y) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpSub16 { + continue + } + t := v_0.Args[1] + x := v_0.Args[0] + if v_1.Op != OpAdd16 { + continue + } + _ = v_1.Args[1] + v_1_0 := v_1.Args[0] + v_1_1 := v_1.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 { + if t != v_1_0 { + continue + } + y := v_1_1 + v.reset(OpAdd16) + v.AddArg2(x, y) + return true + } + } + break + } // match: (Add16 (Const16 [1]) (Com16 x)) // result: (Neg16 x) for { @@ -1146,6 +1173,33 @@ func rewriteValuegeneric_OpAdd32(v *Value) bool { } break } + // match: (Add32 (Sub32 x t) (Add32 t y)) + // result: (Add32 x y) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpSub32 { + continue + } + t := v_0.Args[1] + x := v_0.Args[0] + if v_1.Op != OpAdd32 { + continue + } + _ = v_1.Args[1] + v_1_0 := v_1.Args[0] + v_1_1 := v_1.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 { + if t != v_1_0 { + continue + } + y := v_1_1 + v.reset(OpAdd32) + v.AddArg2(x, y) + return true + } + } + break + } // match: (Add32 (Const32 [1]) (Com32 x)) // result: (Neg32 x) for { @@ -1759,6 +1813,33 @@ func rewriteValuegeneric_OpAdd64(v *Value) bool { } break } + // match: (Add64 (Sub64 x t) (Add64 t y)) + // result: (Add64 x y) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpSub64 { + continue + } + t := v_0.Args[1] + x := v_0.Args[0] + if v_1.Op != OpAdd64 { + continue + } + _ = v_1.Args[1] + v_1_0 := v_1.Args[0] + v_1_1 := v_1.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 { + if t != v_1_0 { + continue + } + y := v_1_1 + v.reset(OpAdd64) + v.AddArg2(x, y) + return true + } + } + break + } // match: (Add64 (Const64 [1]) (Com64 x)) // result: (Neg64 x) for { @@ -2372,6 +2453,33 @@ func rewriteValuegeneric_OpAdd8(v *Value) bool { } break } + // match: (Add8 (Sub8 x t) (Add8 t y)) + // result: (Add8 x y) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpSub8 { + continue + } + t := v_0.Args[1] + x := v_0.Args[0] + if v_1.Op != OpAdd8 { + continue + } + _ = v_1.Args[1] + v_1_0 := v_1.Args[0] + v_1_1 := v_1.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 { + if t != v_1_0 { + continue + } + y := v_1_1 + v.reset(OpAdd8) + v.AddArg2(x, y) + return true + } + } + break + } // match: (Add8 (Const8 [1]) (Com8 x)) // result: (Neg8 x) for { @@ -28976,6 +29084,36 @@ func rewriteValuegeneric_OpSub16(v *Value) bool { v.AuxInt = int16ToAuxInt(-1) return true } + // match: (Sub16 (Add16 t x) (Add16 t y)) + // result: (Sub16 x y) + for { + if v_0.Op != OpAdd16 { + break + } + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + t := v_0_0 + x := v_0_1 + if v_1.Op != OpAdd16 { + continue + } + _ = v_1.Args[1] + v_1_0 := v_1.Args[0] + v_1_1 := v_1.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 { + if t != v_1_0 { + continue + } + y := v_1_1 + v.reset(OpSub16) + v.AddArg2(x, y) + return true + } + } + break + } // match: (Sub16 (Add16 x y) x) // result: y for { @@ -29319,6 +29457,36 @@ func rewriteValuegeneric_OpSub32(v *Value) bool { v.AuxInt = int32ToAuxInt(-1) return true } + // match: (Sub32 (Add32 t x) (Add32 t y)) + // result: (Sub32 x y) + for { + if v_0.Op != OpAdd32 { + break + } + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + t := v_0_0 + x := v_0_1 + if v_1.Op != OpAdd32 { + continue + } + _ = v_1.Args[1] + v_1_0 := v_1.Args[0] + v_1_1 := v_1.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 { + if t != v_1_0 { + continue + } + y := v_1_1 + v.reset(OpSub32) + v.AddArg2(x, y) + return true + } + } + break + } // match: (Sub32 (Add32 x y) x) // result: y for { @@ -29686,6 +29854,36 @@ func rewriteValuegeneric_OpSub64(v *Value) bool { v.AuxInt = int64ToAuxInt(-1) return true } + // match: (Sub64 (Add64 t x) (Add64 t y)) + // result: (Sub64 x y) + for { + if v_0.Op != OpAdd64 { + break + } + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + t := v_0_0 + x := v_0_1 + if v_1.Op != OpAdd64 { + continue + } + _ = v_1.Args[1] + v_1_0 := v_1.Args[0] + v_1_1 := v_1.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 { + if t != v_1_0 { + continue + } + y := v_1_1 + v.reset(OpSub64) + v.AddArg2(x, y) + return true + } + } + break + } // match: (Sub64 (Add64 x y) x) // result: y for { @@ -30053,6 +30251,36 @@ func rewriteValuegeneric_OpSub8(v *Value) bool { v.AuxInt = int8ToAuxInt(-1) return true } + // match: (Sub8 (Add8 t x) (Add8 t y)) + // result: (Sub8 x y) + for { + if v_0.Op != OpAdd8 { + break + } + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + t := v_0_0 + x := v_0_1 + if v_1.Op != OpAdd8 { + continue + } + _ = v_1.Args[1] + v_1_0 := v_1.Args[0] + v_1_1 := v_1.Args[1] + for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 { + if t != v_1_0 { + continue + } + y := v_1_1 + v.reset(OpSub8) + v.AddArg2(x, y) + return true + } + } + break + } // match: (Sub8 (Add8 x y) x) // result: y for { |
