From 3e11e61f3ced03d48e7d27ff6e51a3b1c0425db7 Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Sun, 28 Aug 2022 05:23:28 +1000 Subject: [PATCH] cmd/compile: optimise subtraction with const on riscv64 Convert subtraction from const to a negated ADDI with negative const value, where possible. At worst this avoids a register load and uses the same number of instructions. At best, this allows for further optimisation to occur, particularly where equality is involved. For example, this sequence: li t0,-1 sub t1,t0,a0 snez t1,t1 Becomes: addi t0,a0,1 snez t0,t0 Removes more than 2000 instructions from the Go binary on linux/riscv64. Change-Id: I68f3be897bc645d4a8fa3ab3cef165a00a74df19 Reviewed-on: https://go-review.googlesource.com/c/go/+/426263 Reviewed-by: Meng Zhuo Reviewed-by: Heschi Kreinick Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot Run-TryBot: Joel Sing --- .../compile/internal/ssa/gen/RISCV64.rules | 3 ++- .../compile/internal/ssa/rewriteRISCV64.go | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/ssa/gen/RISCV64.rules b/src/cmd/compile/internal/ssa/gen/RISCV64.rules index a49a9148ea..9d3cb06697 100644 --- a/src/cmd/compile/internal/ssa/gen/RISCV64.rules +++ b/src/cmd/compile/internal/ssa/gen/RISCV64.rules @@ -748,8 +748,9 @@ (SRL x (MOVDconst [val])) => (SRLI [int64(val&63)] x) (SRA x (MOVDconst [val])) => (SRAI [int64(val&63)] x) -// Convert subtraction of a const into ADDI with negative immediate, where possible. +// Convert const subtraction into ADDI with negative immediate, where possible. (SUB x (MOVDconst [val])) && is32Bit(-val) => (ADDI [-val] x) +(SUB (MOVDconst [val]) y) && is32Bit(-val) => (NEG (ADDI [-val] y)) // Subtraction of zero. (SUB x (MOVDconst [0])) => x diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go index 052e9d2039..6244488992 100644 --- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go +++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go @@ -5495,6 +5495,7 @@ func rewriteValueRISCV64_OpRISCV64SRLI(v *Value) bool { func rewriteValueRISCV64_OpRISCV64SUB(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + b := v.Block // match: (SUB x (MOVDconst [val])) // cond: is32Bit(-val) // result: (ADDI [-val] x) @@ -5512,6 +5513,26 @@ func rewriteValueRISCV64_OpRISCV64SUB(v *Value) bool { v.AddArg(x) return true } + // match: (SUB (MOVDconst [val]) y) + // cond: is32Bit(-val) + // result: (NEG (ADDI [-val] y)) + for { + t := v.Type + if v_0.Op != OpRISCV64MOVDconst { + break + } + val := auxIntToInt64(v_0.AuxInt) + y := v_1 + if !(is32Bit(-val)) { + break + } + v.reset(OpRISCV64NEG) + v0 := b.NewValue0(v.Pos, OpRISCV64ADDI, t) + v0.AuxInt = int64ToAuxInt(-val) + v0.AddArg(y) + v.AddArg(v0) + return true + } // match: (SUB x (MOVDconst [0])) // result: x for { -- 2.50.0