From 3a29ebeef985efb12d2b8670f50b146e9a2815ca Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Sat, 21 Feb 2026 03:29:09 +1100 Subject: [PATCH] cmd/compile: additional optimisation for CZEROEQZ/CZERONEZ on riscv64 Negation on a condition can be eliminated. Change-Id: I94fab5f019cbaebb2ca589e1d8796a9cb72f3894 Reviewed-on: https://go-review.googlesource.com/c/go/+/748401 Reviewed-by: Xueqi Luo <1824368278@qq.com> Reviewed-by: Cherry Mui Reviewed-by: Keith Randall Reviewed-by: Keith Randall Reviewed-by: Julian Zhu LUCI-TryBot-Result: Go LUCI Auto-Submit: Keith Randall --- .../compile/internal/ssa/_gen/RISCV64.rules | 1 + .../compile/internal/ssa/rewriteRISCV64.go | 24 +++++++++++++++++++ test/codegen/condmove.go | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules index 06130d242d..9e3911ea0c 100644 --- a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules +++ b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules @@ -866,6 +866,7 @@ (OR (CZEROEQZ x (MOVBUreg cond)) (CZERONEZ y (MOVBUreg cond))) (CZERO(EQ|NE)Z x (SNEZ y)) => (CZERO(EQ|NE)Z x y) (CZERO(EQ|NE)Z x (SEQZ y)) => (CZERO(NE|EQ)Z x y) +(CZERO(EQ|NE)Z x (NEG y)) => (CZERO(EQ|NE)Z x y) (CZEROEQZ x x) => x (CZERONEZ x x) => (MOVDconst [0]) (CZERO(EQ|NE)Z (MOVDconst [0]) _) => (MOVDconst [0]) diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go index 1700604422..d5c52c5eb1 100644 --- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go +++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go @@ -3588,6 +3588,18 @@ func rewriteValueRISCV64_OpRISCV64CZEROEQZ(v *Value) bool { v.AddArg2(x, y) return true } + // match: (CZEROEQZ x (NEG y)) + // result: (CZEROEQZ x y) + for { + x := v_0 + if v_1.Op != OpRISCV64NEG { + break + } + y := v_1.Args[0] + v.reset(OpRISCV64CZEROEQZ) + v.AddArg2(x, y) + return true + } // match: (CZEROEQZ x x) // result: x for { @@ -3637,6 +3649,18 @@ func rewriteValueRISCV64_OpRISCV64CZERONEZ(v *Value) bool { v.AddArg2(x, y) return true } + // match: (CZERONEZ x (NEG y)) + // result: (CZERONEZ x y) + for { + x := v_0 + if v_1.Op != OpRISCV64NEG { + break + } + y := v_1.Args[0] + v.reset(OpRISCV64CZERONEZ) + v.AddArg2(x, y) + return true + } // match: (CZERONEZ x x) // result: (MOVDconst [0]) for { diff --git a/test/codegen/condmove.go b/test/codegen/condmove.go index bd2d1540b4..93159d1ca4 100644 --- a/test/codegen/condmove.go +++ b/test/codegen/condmove.go @@ -534,6 +534,6 @@ func constantTimeSelect(v, x, y int) int { // amd64:"CMOVQ" // arm64:"CSEL" // riscv64/rva20u64,riscv64/rva22u64:"SNEZ" "NEG" "AND" "OR" - // riscv64/rva23u64:"NEG" "CZERONEZ" "CZEROEQZ" "OR" -"SNEZ" -"AND" + // riscv64/rva23u64:"CZERONEZ" "CZEROEQZ" "OR" -"SNEZ" -"NEG" -"AND" return subtle.ConstantTimeSelect(v, x, y) }