]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fold negation into subtraction on riscv64
authorJoel Sing <joel@sing.id.au>
Fri, 9 Sep 2022 13:15:46 +0000 (23:15 +1000)
committerJoel Sing <joel@sing.id.au>
Tue, 11 Oct 2022 04:04:13 +0000 (04:04 +0000)
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>
src/cmd/compile/internal/ssa/_gen/RISCV64.rules
src/cmd/compile/internal/ssa/rewriteRISCV64.go

index 6119f3482ba1358f6125fa5699e78a1b525899dc..78c3375e2d60c849a9418bd5f113d73f9c0898f4 100644 (file)
 (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])
index 31ec233e612add932318a1b66c5db4701476d0b6..d362b668c85ad962e41b5573a5bfcb24324845dd 100644 (file)
@@ -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 {