aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2022-08-28 02:32:06 +1000
committerJoel Sing <joel@sing.id.au>2022-09-02 20:14:16 +0000
commit646c3eee06fa4b1b869e8183977aa46d4d4eb646 (patch)
tree14e90bb8314fa3ae0c325eed7447d282ca8a2fe3
parent9154d4a2a4952e35cb091fc254c9f5f1d3f0d409 (diff)
downloadgo-646c3eee06fa4b1b869e8183977aa46d4d4eb646.tar.xz
cmd/compile: negate comparision with FNES/FNED on riscv64
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>
-rw-r--r--src/cmd/compile/internal/ssa/gen/RISCV64.rules6
-rw-r--r--src/cmd/compile/internal/ssa/rewriteRISCV64.go68
2 files changed, 74 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/gen/RISCV64.rules b/src/cmd/compile/internal/ssa/gen/RISCV64.rules
index 82a9c83284..a49a9148ea 100644
--- a/src/cmd/compile/internal/ssa/gen/RISCV64.rules
+++ b/src/cmd/compile/internal/ssa/gen/RISCV64.rules
@@ -620,6 +620,12 @@
(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)
diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
index a46664fc90..052e9d2039 100644
--- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go
+++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
@@ -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 {