]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/ssa: remove double negation with addition on riscv64
authorJoel Sing <joel@sing.id.au>
Sun, 23 Feb 2025 13:37:45 +0000 (00:37 +1100)
committerJoel Sing <joel@sing.id.au>
Sat, 15 Mar 2025 13:04:28 +0000 (06:04 -0700)
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>
src/cmd/compile/internal/ssa/_gen/RISCV64.rules
src/cmd/compile/internal/ssa/rewriteRISCV64.go
test/codegen/arithmetic.go

index 6319746dc781293a469b8aebda421b171df3d04c..5c9ce19773f7ddb91427f1a57f9e632eb545ce13 100644 (file)
 
 // 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
index 165c9799f989f9f375b0dc034413cb53c9c9972e..eb0480e08032e2ab514bd127cffe66acb84b3fc0 100644 (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 {
index beeb5357c45d91884c5f8c49f45f2f732c9e2094..07fd0c961fe96326f2982a63dc88d507e8336771 100644 (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
 }