-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
Proposal Details
Background
The RISC-V Zicond extension provides conditional zero instructions (czero.eqz and czero.nez), which are useful for implementing conditional moves and other conditional operations without branching. This can lead to performance improvements by avoiding branch mispredictions.
Currently, the Go compiler does not generate these instructions for riscv64 targets, even when the underlying hardware supports them. This represents a missed optimization opportunity.
Proposed Solution
Add comprehensive support for the Zicond extension to the Go toolchain for riscv64, including assembler, compiler, and disassembler support. All features are conditionally enabled when buildcfg.GORISCV64 >= 23.
Implementation Details
- Assembler Support (cmd/internal/obj/riscv):
- Add ACZEROEQZ and ACZERONEZ to instruction enum in cpu.go
- Add instruction encoding in inst.go:
- CZEROEQZ: opcode=0x33, funct3=0x5, funct7=0x7
- CZERONEZ: opcode=0x33, funct3=0x7, funct7=0x7
- Add instruction data in obj.go with rIIIEncoding format
- Add instruction names in anames.go
- Add instruction mapping in obj.go for proper register assignment
- Compiler Support (cmd/compile):
Based on the RISC-V Zicond specification, implement comprehensive SSA lowering rules:
RISCV64latelower.rules
// Zicond rules support
(Select <typ.UInt64> cond trueval falseval) => (ADD (CZEROEQZ <typ.UInt64> falseval cond) (CZERONEZ <typ.UInt64> trueval cond))
// Conditional arithmetic operations with Zicond
(CondSelect <t> (ADD x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (ADD x (CZERONEZ <t> y z))
(CondSelect <t> (ADD x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (ADD x (CZEROEQZ <t> y z))
// Conditional subtract operations with Zicond
(CondSelect <t> (SUB x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (SUB x (CZERONEZ <t> y z))
(CondSelect <t> (SUB x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (SUB x (CZEROEQZ <t> y z))
// Conditional bitwise-or operations with Zicond
(CondSelect <t> (OR x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (OR x (CZERONEZ <t> y z))
(CondSelect <t> (OR x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (OR x (CZEROEQZ <t> y z))
// Conditional bitwise-xor operations with Zicond
(CondSelect <t> (XOR x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (XOR x (CZERONEZ <t> y z))
(CondSelect <t> (XOR x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (XOR x (CZEROEQZ <t> y z))
// Conditional bitwise-and operations with Zicond
(CondSelect <t> (AND x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (OR (AND <t> x y) (CZEROEQZ <t> x z))
(CondSelect <t> (AND x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (OR (AND <t> x y) (CZERONEZ <t> x z))
// (z == 0) ? x : y
(CondSelect <t> x y (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (OR (CZERONEZ <t> x z) (CZEROEQZ <t> y z))
// (z != 0) ? x : y
(CondSelect <t> x y (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (OR (CZEROEQZ <t> x z) (CZERONEZ <t> y z))
(CondSelect <t> x y cond) && buildcfg.GORISCV64 >= 23 => (OR (CZEROEQZ <t> x cond) (CZERONEZ <t> y cond))
These rules cover various conditional select patterns as specified in the RISC-V Zicond extension documentation, enabling efficient code generation for different conditional scenarios.
- Disassembler Support (src/cmd/internal/obj/riscv、cmd/vendor/golang.org/x/arch/riscv64/riscv64asm):
- Add instruction definitions in tables.go for proper disassembly
- Add instFormat entries with correct encoding masks and values
- Add instruction names to opstr array
- Build Configuration:
- All Zicond features are conditionally enabled when buildcfg.GORISCV64 >= 23
- This ensures compatibility with older RISC-V targets that don't support Zicond
Example
// Go code like:
func condSelect(x, y int, cond bool) int {
if cond {
return x
}
return y
}
// Could be compiled to use czero.nez/czero.eqz instead of branching code
// when GORISCV64 >= 23
Additional Context
The specification for the Zicond extension can be found in the ratified RVA23 profile or other RISC-V ISA documents.
I am willing to work on implementing this feature and submit a CL for review.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status