cmd/compile/internal/ssa: remove double negation with addition on riscv64

On riscv64, subtraction from a constant is typically implemented as an
ADDI with the negative constant, followed by a negation. However this can
lead to multiple NEG/ADDI/NEG sequences that can be optimised out.

For example, runtime.(*_panic).nextDefer currently contains:

   lbu     t0, 0(t0)
   addi    t0, t0, -8
   neg     t0, t0
   addi    t0, t0, -7
   neg     t0, t0

Which is now optimised to:

   lbu     t0, 0(t0)
   addi    t0, t0, -1

Change-Id: Idf5815e6db2e3705cc4a4811ca9130a064ae3d80
Reviewed-on: https://go-review.googlesource.com/c/go/+/652318
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Meng Zhuo <mengzhuo1203@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mark Ryan <markdryan@rivosinc.com>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Joel Sing 2025-02-24 00:37:45 +11:00
parent a8f2e63f2f
commit 10d070668c
3 changed files with 24 additions and 1 deletions

View File

@ -732,6 +732,7 @@
// Double negation.
(NEG (NEG x)) => x
(NEG <t> s:(ADDI [val] (NEG x))) && s.Uses == 1 && is32Bit(-val) => (ADDI [-val] x)
// Addition of zero or two constants.
(ADDI [0] x) => x

View File

@ -6105,6 +6105,28 @@ func rewriteValueRISCV64_OpRISCV64NEG(v *Value) bool {
v.copyOf(x)
return true
}
// match: (NEG <t> s:(ADDI [val] (NEG x)))
// cond: s.Uses == 1 && is32Bit(-val)
// result: (ADDI [-val] x)
for {
s := v_0
if s.Op != OpRISCV64ADDI {
break
}
val := auxIntToInt64(s.AuxInt)
s_0 := s.Args[0]
if s_0.Op != OpRISCV64NEG {
break
}
x := s_0.Args[0]
if !(s.Uses == 1 && is32Bit(-val)) {
break
}
v.reset(OpRISCV64ADDI)
v.AuxInt = int64ToAuxInt(-val)
v.AddArg(x)
return true
}
// match: (NEG (MOVDconst [x]))
// result: (MOVDconst [-x])
for {

View File

@ -92,7 +92,7 @@ func SubFromConst(a int) int {
func SubFromConstNeg(a int) int {
// ppc64x: `ADD\t[$]40,\sR[0-9]+,\sR`
// riscv64: "NEG","ADDI\t\\$-40","NEG"
// riscv64: "ADDI\t\\$40",-"NEG"
c := 40 - (-a)
return c
}