]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: negate comparision with FNES/FNED on riscv64
authorJoel Sing <joel@sing.id.au>
Sat, 27 Aug 2022 16:32:06 +0000 (02:32 +1000)
committerJoel Sing <joel@sing.id.au>
Fri, 2 Sep 2022 20:14:16 +0000 (20:14 +0000)
The FNES and FNED instructions are pseudo-instructions, which the
assembler expands to FEQS/NEG or FEQD/NEG - if we're comparing the
result via a branch instruction, we can avoid an instruction by
negating both the branch comparision and the floating point
comparision.

This only removes a handful of instructions from the Go binary,
however, it will provide benefit to floating point intensive code.

Change-Id: I4e3124440b7659acc4d9bc9948b755a4900a422f
Reviewed-on: https://go-review.googlesource.com/c/go/+/426261
Reviewed-by: Meng Zhuo <mzh@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Joel Sing <joel@sing.id.au>
Run-TryBot: Meng Zhuo <mzh@golangcn.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
src/cmd/compile/internal/ssa/gen/RISCV64.rules
src/cmd/compile/internal/ssa/rewriteRISCV64.go

index 82a9c8328423b941d43e543d621411ef0b2b09f3..a49a9148eafcd3297d432f1566632c7526c4dcbd 100644 (file)
 (BEQZ (NEG x) yes no) => (BEQZ x yes no)
 (BNEZ (NEG x) yes no) => (BNEZ x yes no)
 
+// Negate comparision with FNES/FNED.
+(BEQZ (FNES <t> x y) yes no) => (BNEZ (FEQS <t> x y) yes no)
+(BNEZ (FNES <t> x y) yes no) => (BEQZ (FEQS <t> x y) yes no)
+(BEQZ (FNED <t> x y) yes no) => (BNEZ (FEQD <t> x y) yes no)
+(BNEZ (FNED <t> x y) yes no) => (BEQZ (FEQD <t> x 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 a46664fc90e101047fb1d6a7613855df88585d6e..052e9d20395329e7c1155f837be7e94f954968d9 100644 (file)
@@ -7847,6 +7847,40 @@ func rewriteBlockRISCV64(b *Block) bool {
                        b.resetWithControl(BlockRISCV64BEQZ, x)
                        return true
                }
+               // match: (BEQZ (FNES <t> x y) yes no)
+               // result: (BNEZ (FEQS <t> x y) yes no)
+               for b.Controls[0].Op == OpRISCV64FNES {
+                       v_0 := b.Controls[0]
+                       t := v_0.Type
+                       _ = v_0.Args[1]
+                       v_0_0 := v_0.Args[0]
+                       v_0_1 := v_0.Args[1]
+                       for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                               x := v_0_0
+                               y := v_0_1
+                               v0 := b.NewValue0(v_0.Pos, OpRISCV64FEQS, t)
+                               v0.AddArg2(x, y)
+                               b.resetWithControl(BlockRISCV64BNEZ, v0)
+                               return true
+                       }
+               }
+               // match: (BEQZ (FNED <t> x y) yes no)
+               // result: (BNEZ (FEQD <t> x y) yes no)
+               for b.Controls[0].Op == OpRISCV64FNED {
+                       v_0 := b.Controls[0]
+                       t := v_0.Type
+                       _ = v_0.Args[1]
+                       v_0_0 := v_0.Args[0]
+                       v_0_1 := v_0.Args[1]
+                       for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                               x := v_0_0
+                               y := v_0_1
+                               v0 := b.NewValue0(v_0.Pos, OpRISCV64FEQD, t)
+                               v0.AddArg2(x, y)
+                               b.resetWithControl(BlockRISCV64BNEZ, v0)
+                               return true
+                       }
+               }
                // match: (BEQZ (SUB x y) yes no)
                // result: (BEQ x y yes no)
                for b.Controls[0].Op == OpRISCV64SUB {
@@ -7968,6 +8002,40 @@ func rewriteBlockRISCV64(b *Block) bool {
                        b.resetWithControl(BlockRISCV64BNEZ, x)
                        return true
                }
+               // match: (BNEZ (FNES <t> x y) yes no)
+               // result: (BEQZ (FEQS <t> x y) yes no)
+               for b.Controls[0].Op == OpRISCV64FNES {
+                       v_0 := b.Controls[0]
+                       t := v_0.Type
+                       _ = v_0.Args[1]
+                       v_0_0 := v_0.Args[0]
+                       v_0_1 := v_0.Args[1]
+                       for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                               x := v_0_0
+                               y := v_0_1
+                               v0 := b.NewValue0(v_0.Pos, OpRISCV64FEQS, t)
+                               v0.AddArg2(x, y)
+                               b.resetWithControl(BlockRISCV64BEQZ, v0)
+                               return true
+                       }
+               }
+               // match: (BNEZ (FNED <t> x y) yes no)
+               // result: (BEQZ (FEQD <t> x y) yes no)
+               for b.Controls[0].Op == OpRISCV64FNED {
+                       v_0 := b.Controls[0]
+                       t := v_0.Type
+                       _ = v_0.Args[1]
+                       v_0_0 := v_0.Args[0]
+                       v_0_1 := v_0.Args[1]
+                       for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                               x := v_0_0
+                               y := v_0_1
+                               v0 := b.NewValue0(v_0.Pos, OpRISCV64FEQD, t)
+                               v0.AddArg2(x, y)
+                               b.resetWithControl(BlockRISCV64BEQZ, v0)
+                               return true
+                       }
+               }
                // match: (BNEZ (SUB x y) yes no)
                // result: (BNE x y yes no)
                for b.Controls[0].Op == OpRISCV64SUB {