aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2022-09-09 23:15:46 +1000
committerJoel Sing <joel@sing.id.au>2022-10-11 04:04:13 +0000
commit4274ffd4b8bcef4e07cfdef9405a2e33f935d079 (patch)
tree02e5f5e761059f3db2896e12040ec3764dd7c9f0 /src
parentba8c94b5f255bf84d05cf90d3d66621ffd2e0fab (diff)
downloadgo-4274ffd4b8bcef4e07cfdef9405a2e33f935d079.tar.xz
cmd/compile: fold negation into subtraction on riscv64
Fold negation into subtraction and avoid double negation. This removes around 500 instructions from the Go binary on riscv64. Change-Id: I4aac6c87baa2a0759b180ba87876d488a23df6d7 Reviewed-on: https://go-review.googlesource.com/c/go/+/431105 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Joedian Reid <joedian@golang.org> Reviewed-by: Wayne Zuo <wdvxdr@golangcn.org> Run-TryBot: Joel Sing <joel@sing.id.au> Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/ssa/_gen/RISCV64.rules7
-rw-r--r--src/cmd/compile/internal/ssa/rewriteRISCV64.go49
2 files changed, 56 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules
index 6119f3482b..78c3375e2d 100644
--- a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules
@@ -778,6 +778,13 @@
(SUB (MOVDconst [0]) x) => (NEG x)
(SUBW (MOVDconst [0]) x) => (NEGW x)
+// Fold negation into subtraction.
+(NEG (SUB x y)) => (SUB y x)
+(NEG <t> s:(ADDI [val] (SUB x y))) && s.Uses == 1 && is32Bit(-val) => (ADDI [-val] (SUB <t> y x))
+
+// Double negation.
+(NEG (NEG x)) => x
+
// Addition of zero or two constants.
(ADDI [0] x) => x
(ADDI [x] (MOVDconst [y])) && is32Bit(x + y) => (MOVDconst [x + y])
diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
index 31ec233e61..d362b668c8 100644
--- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go
+++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
@@ -5437,6 +5437,55 @@ func rewriteValueRISCV64_OpRISCV64MOVWstorezero(v *Value) bool {
}
func rewriteValueRISCV64_OpRISCV64NEG(v *Value) bool {
v_0 := v.Args[0]
+ b := v.Block
+ // match: (NEG (SUB x y))
+ // result: (SUB y x)
+ for {
+ if v_0.Op != OpRISCV64SUB {
+ break
+ }
+ y := v_0.Args[1]
+ x := v_0.Args[0]
+ v.reset(OpRISCV64SUB)
+ v.AddArg2(y, x)
+ return true
+ }
+ // match: (NEG <t> s:(ADDI [val] (SUB x y)))
+ // cond: s.Uses == 1 && is32Bit(-val)
+ // result: (ADDI [-val] (SUB <t> y x))
+ for {
+ t := v.Type
+ s := v_0
+ if s.Op != OpRISCV64ADDI {
+ break
+ }
+ val := auxIntToInt64(s.AuxInt)
+ s_0 := s.Args[0]
+ if s_0.Op != OpRISCV64SUB {
+ break
+ }
+ y := s_0.Args[1]
+ x := s_0.Args[0]
+ if !(s.Uses == 1 && is32Bit(-val)) {
+ break
+ }
+ v.reset(OpRISCV64ADDI)
+ v.AuxInt = int64ToAuxInt(-val)
+ v0 := b.NewValue0(v.Pos, OpRISCV64SUB, t)
+ v0.AddArg2(y, x)
+ v.AddArg(v0)
+ return true
+ }
+ // match: (NEG (NEG x))
+ // result: x
+ for {
+ if v_0.Op != OpRISCV64NEG {
+ break
+ }
+ x := v_0.Args[0]
+ v.copyOf(x)
+ return true
+ }
// match: (NEG (MOVDconst [x]))
// result: (MOVDconst [-x])
for {