]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimise subtraction with const on riscv64
authorJoel Sing <joel@sing.id.au>
Sat, 27 Aug 2022 19:23:28 +0000 (05:23 +1000)
committerJoel Sing <joel@sing.id.au>
Fri, 2 Sep 2022 20:14:40 +0000 (20:14 +0000)
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 <mzh@golangcn.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Joel Sing <joel@sing.id.au>

src/cmd/compile/internal/ssa/gen/RISCV64.rules
src/cmd/compile/internal/ssa/rewriteRISCV64.go

index a49a9148eafcd3297d432f1566632c7526c4dcbd..9d3cb06697d4e74fdc8912b439857cc70752e788 100644 (file)
 (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 <t> (MOVDconst [val]) y) && is32Bit(-val) => (NEG (ADDI <t> [-val] y))
 
 // Subtraction of zero.
 (SUB  x (MOVDconst [0])) => x
index 052e9d20395329e7c1155f837be7e94f954968d9..6244488992d7e29672005489d26bcd33cfcb9f0a 100644 (file)
@@ -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 <t> (MOVDconst [val]) y)
+       // cond: is32Bit(-val)
+       // result: (NEG (ADDI <t> [-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 {