Skip to content

Commit a2d8f8d

Browse files
committed
cmd/compile/internal/ssa: add codegen for Zicond extension on riscv64
This patch adds code generation support for the Zicond extension. We convert branches into CondSelect operations in branchelim and rewrite them into Zicond instructions. Additionally, optimization rules have been added to optimize more conditional branch scenarios based on the riscv-isa-manual. Follow-up to CL 631595 Updates #75350 Change-Id: If3f6dbff2fc165addfb4e511e0ac618419d59103
1 parent d7a38ad commit a2d8f8d

File tree

7 files changed

+625
-2
lines changed

7 files changed

+625
-2
lines changed

src/cmd/compile/internal/riscv64/ssa.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
294294
ssa.OpRISCV64FADDD, ssa.OpRISCV64FSUBD, ssa.OpRISCV64FMULD, ssa.OpRISCV64FDIVD,
295295
ssa.OpRISCV64FEQD, ssa.OpRISCV64FNED, ssa.OpRISCV64FLTD, ssa.OpRISCV64FLED, ssa.OpRISCV64FSGNJD,
296296
ssa.OpRISCV64MIN, ssa.OpRISCV64MAX, ssa.OpRISCV64MINU, ssa.OpRISCV64MAXU,
297-
ssa.OpRISCV64SH1ADD, ssa.OpRISCV64SH2ADD, ssa.OpRISCV64SH3ADD:
297+
ssa.OpRISCV64SH1ADD, ssa.OpRISCV64SH2ADD, ssa.OpRISCV64SH3ADD,
298+
ssa.OpRISCV64CZEROEQZ, ssa.OpRISCV64CZERONEZ:
298299
r := v.Reg()
299300
r1 := v.Args[0].Reg()
300301
r2 := v.Args[1].Reg()

src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,10 @@ func init() {
520520
// ====+=============================
521521
{name: "FCLASSS", argLength: 1, reg: fpgp, asm: "FCLASSS", typ: "Int64"}, // classify float32
522522
{name: "FCLASSD", argLength: 1, reg: fpgp, asm: "FCLASSD", typ: "Int64"}, // classify float64
523+
524+
// RISC-V Integer Conditional (Zicond) operations extension
525+
{name: "CZEROEQZ", argLength: 2, reg: gp21, asm: "CZEROEQZ"},
526+
{name: "CZERONEZ", argLength: 2, reg: gp21, asm: "CZERONEZ"},
523527
}
524528

525529
RISCV64blocks := []blockData{

src/cmd/compile/internal/ssa/_gen/RISCV64latelower.rules

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,33 @@
2323
(SRAI [0] x) => x
2424
(SRLI [0] x) => x
2525
(SLLI [0] x) => x
26+
27+
// "Zicond" Extension for Integer Conditional Operations
28+
// (x == 0) ? x : y
29+
(CondSelect <t> x y (SEQZ x)) && buildcfg.GORISCV64 >= 23 => (CZEROEQZ <t> y x)
30+
// (z == 0) ? (x + y) : y
31+
(CondSelect <t> (ADD x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (ADD x (CZERONEZ <t> y z))
32+
// (z != 0) ? (x + y) : y
33+
(CondSelect <t> (ADD x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (ADD x (CZEROEQZ <t> y z))
34+
// (z == 0) ? (x - y) : y
35+
(CondSelect <t> (SUB x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (SUB x (CZERONEZ <t> y z))
36+
// (z != 0) ? (x - y) : y
37+
(CondSelect <t> (SUB x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (SUB x (CZEROEQZ <t> y z))
38+
// (z == 0) ? (x | y) : y
39+
(CondSelect <t> (OR x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (OR x (CZERONEZ <t> y z))
40+
// (z != 0) ? (x | y) : y
41+
(CondSelect <t> (OR x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (OR x (CZEROEQZ <t> y z))
42+
// (z == 0) ? (x ^ y) : y
43+
(CondSelect <t> (XOR x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (XOR x (CZERONEZ <t> y z))
44+
// (z != 0) ? (x ^ y) : y
45+
(CondSelect <t> (XOR x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (XOR x (CZEROEQZ <t> y z))
46+
// (z == 0) ? (x & y) : y
47+
(CondSelect <t> (AND x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (OR (AND <t> x y) (CZEROEQZ <t> x z))
48+
// (z != 0) ? (x & y) : y
49+
(CondSelect <t> (AND x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (OR (AND <t> x y) (CZERONEZ <t> x z))
50+
// (z == 0) ? x : y
51+
(CondSelect <t> x y (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (OR (CZERONEZ <t> x z) (CZEROEQZ <t> y z))
52+
// (z != 0) ? x : y
53+
(CondSelect <t> x y (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (OR (CZEROEQZ <t> x z) (CZERONEZ <t> y z))
54+
// Make sure we can rewrite all CondSelects.
55+
(CondSelect <t> x y cond) && buildcfg.GORISCV64 >= 23 => (OR (CZEROEQZ <t> x cond) (CZERONEZ <t> y cond))

src/cmd/compile/internal/ssa/branchelim.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
package ssa
66

7-
import "cmd/internal/src"
7+
import (
8+
"cmd/internal/src"
9+
"internal/buildcfg"
10+
)
811

912
// branchelim tries to eliminate branches by
1013
// generating CondSelect instructions.
@@ -24,6 +27,10 @@ func branchelim(f *Func) {
2427
switch f.Config.arch {
2528
case "arm64", "ppc64le", "ppc64", "amd64", "wasm", "loong64":
2629
// implemented
30+
case "riscv64":
31+
if buildcfg.GORISCV64 < 23 {
32+
return
33+
}
2734
default:
2835
return
2936
}

src/cmd/compile/internal/ssa/opGen.go

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)