]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: absorb NEG into branch when possible on riscv64
authorJoel Sing <joel@sing.id.au>
Tue, 17 Aug 2021 09:09:33 +0000 (19:09 +1000)
committerJoel Sing <joel@sing.id.au>
Sat, 21 Aug 2021 11:23:14 +0000 (11:23 +0000)
We can end up with this situation due to our equality tests being based on
'SEQZ (SUB x y)' - if x is a zero valued constant, 'SUB x y' can be converted
to 'NEG x'. When used with a branch the SEQZ can be absorbed, leading to
'BNEZ (NEG x)' where the NEG is redundant.

Removes around 1700 instructions from the go binary on riscv64.

Change-Id: I947a080d8bf7d2d6378ab114172e2342ce2c51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/342850
Trust: Joel Sing <joel@sing.id.au>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>

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

index 1414b2b34d5da51838182824e1ec564228b83d75..4eb48e3928f587f5537fd984e779eb8da2aa497a 100644 (file)
 (BNEZ (SEQZ x) yes no) => (BEQZ x yes no)
 (BNEZ (SNEZ x) yes no) => (BNEZ x yes no)
 
+// Absorb NEG into branch when possible.
+(BEQZ x:(NEG y) yes no) && x.Uses == 1 => (BEQZ y yes no)
+(BNEZ x:(NEG y) yes no) && x.Uses == 1 => (BNEZ y yes no)
+
 // Convert BEQZ/BNEZ into more optimal branch conditions.
 (BEQZ (SUB x y) yes no) => (BEQ x y yes no)
 (BNEZ (SUB x y) yes no) => (BNE x y yes no)
index 9323cda55d2cef85f77bcbc594a1ceaae2bce427..641be038dba02800393c8835afcacfbf5c25a805 100644 (file)
@@ -6102,6 +6102,18 @@ func rewriteBlockRISCV64(b *Block) bool {
                        b.resetWithControl(BlockRISCV64BEQZ, x)
                        return true
                }
+               // match: (BEQZ x:(NEG y) yes no)
+               // cond: x.Uses == 1
+               // result: (BEQZ y yes no)
+               for b.Controls[0].Op == OpRISCV64NEG {
+                       x := b.Controls[0]
+                       y := x.Args[0]
+                       if !(x.Uses == 1) {
+                               break
+                       }
+                       b.resetWithControl(BlockRISCV64BEQZ, y)
+                       return true
+               }
                // match: (BEQZ (SUB x y) yes no)
                // result: (BEQ x y yes no)
                for b.Controls[0].Op == OpRISCV64SUB {
@@ -6215,6 +6227,18 @@ func rewriteBlockRISCV64(b *Block) bool {
                        b.resetWithControl(BlockRISCV64BNEZ, x)
                        return true
                }
+               // match: (BNEZ x:(NEG y) yes no)
+               // cond: x.Uses == 1
+               // result: (BNEZ y yes no)
+               for b.Controls[0].Op == OpRISCV64NEG {
+                       x := b.Controls[0]
+                       y := x.Args[0]
+                       if !(x.Uses == 1) {
+                               break
+                       }
+                       b.resetWithControl(BlockRISCV64BNEZ, y)
+                       return true
+               }
                // match: (BNEZ (SUB x y) yes no)
                // result: (BNE x y yes no)
                for b.Controls[0].Op == OpRISCV64SUB {