diff options
author | fanzha02 <fannie.zhang@arm.com> | 2020-05-28 18:11:52 +0800 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2020-08-24 14:52:54 +0000 |
commit | d556c251a1f1506f68e1e4064c3537948ff667a3 (patch) | |
tree | de93499d86a24e3b777265f99122c161ce3ac768 /test/codegen/arithmetic.go | |
parent | 4e4d5df0b0af23d2fcb5690e89f27bd7e64e48f1 (diff) | |
download | go-git-d556c251a1f1506f68e1e4064c3537948ff667a3.tar.gz |
cmd/compile: add more generic rewrite rules to reassociate (op (op y C) x|C)
With this patch, opt pass can expose more obvious constant-folding
opportunites.
Example:
func test(i int) int {return (i+8)-(i+4)}
The previous version:
MOVD "".i(FP), R0
ADD $8, R0, R1
ADD $4, R0, R0
SUB R0, R1, R0
MOVD R0, "".~r1+8(FP)
RET (R30)
The optimized version:
MOVD $4, R0
MOVD R0, "".~r1+8(FP)
RET (R30)
This patch removes some existing reassociation rules, such as "x+(z-C)",
because the current generic rewrite rules will canonicalize "x-const"
to "x+(-const)", making "x+(z-C)" equal to "x+(z+(-C))".
This patch also adds test cases.
Change-Id: I857108ba0b5fcc18a879eeab38e2551bc4277797
Reviewed-on: https://go-review.googlesource.com/c/go/+/237137
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'test/codegen/arithmetic.go')
-rw-r--r-- | test/codegen/arithmetic.go | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/test/codegen/arithmetic.go b/test/codegen/arithmetic.go index 45fdb68903..afd4d66bd9 100644 --- a/test/codegen/arithmetic.go +++ b/test/codegen/arithmetic.go @@ -462,7 +462,6 @@ func addSpecial(a, b, c uint32) (uint32, uint32, uint32) { return a, b, c } - // Divide -> shift rules usually require fixup for negative inputs. // If the input is non-negative, make sure the fixup is eliminated. func divInt(v int64) int64 { @@ -472,3 +471,33 @@ func divInt(v int64) int64 { // amd64:-`.*SARQ.*63,`, -".*SHRQ", ".*SARQ.*[$]9," return v / 512 } + +// The reassociate rules "x - (z + C) -> (x - z) - C" and +// "(z + C) -x -> C + (z - x)" can optimize the following cases. +func constantFold1(i0, j0, i1, j1, i2, j2, i3, j3 int) (int, int, int, int) { + // arm64:"SUB","ADD\t[$]2" + r0 := (i0 + 3) - (j0 + 1) + // arm64:"SUB","SUB\t[$]4" + r1 := (i1 - 3) - (j1 + 1) + // arm64:"SUB","ADD\t[$]4" + r2 := (i2 + 3) - (j2 - 1) + // arm64:"SUB","SUB\t[$]2" + r3 := (i3 - 3) - (j3 - 1) + return r0, r1, r2, r3 +} + +// The reassociate rules "x - (z + C) -> (x - z) - C" and +// "(C - z) - x -> C - (z + x)" can optimize the following cases. +func constantFold2(i0, j0, i1, j1 int) (int, int) { + // arm64:"ADD","MOVD\t[$]2","SUB" + r0 := (3 - i0) - (j0 + 1) + // arm64:"ADD","MOVD\t[$]4","SUB" + r1 := (3 - i1) - (j1 - 1) + return r0, r1 +} + +func constantFold3(i, j int) int { + // arm64: "MOVD\t[$]30","MUL",-"ADD",-"LSL" + r := (5 * i) * (6 * j) + return r +} |