From a2d8f8d5d459c05429c9903321529ad149cb2ac4 Mon Sep 17 00:00:00 2001 From: lxq015 <1824368278@qq.com> Date: Mon, 15 Sep 2025 13:50:03 +0800 Subject: [PATCH 1/3] 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 --- src/cmd/compile/internal/riscv64/ssa.go | 3 +- .../compile/internal/ssa/_gen/RISCV64Ops.go | 4 + .../internal/ssa/_gen/RISCV64latelower.rules | 30 ++ src/cmd/compile/internal/ssa/branchelim.go | 9 +- src/cmd/compile/internal/ssa/opGen.go | 30 ++ .../internal/ssa/rewriteRISCV64latelower.go | 371 ++++++++++++++++++ test/codegen/zicond.go | 180 +++++++++ 7 files changed, 625 insertions(+), 2 deletions(-) create mode 100644 test/codegen/zicond.go diff --git a/src/cmd/compile/internal/riscv64/ssa.go b/src/cmd/compile/internal/riscv64/ssa.go index 61de983bb02c00..5c664e01397d1f 100644 --- a/src/cmd/compile/internal/riscv64/ssa.go +++ b/src/cmd/compile/internal/riscv64/ssa.go @@ -294,7 +294,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { ssa.OpRISCV64FADDD, ssa.OpRISCV64FSUBD, ssa.OpRISCV64FMULD, ssa.OpRISCV64FDIVD, ssa.OpRISCV64FEQD, ssa.OpRISCV64FNED, ssa.OpRISCV64FLTD, ssa.OpRISCV64FLED, ssa.OpRISCV64FSGNJD, ssa.OpRISCV64MIN, ssa.OpRISCV64MAX, ssa.OpRISCV64MINU, ssa.OpRISCV64MAXU, - ssa.OpRISCV64SH1ADD, ssa.OpRISCV64SH2ADD, ssa.OpRISCV64SH3ADD: + ssa.OpRISCV64SH1ADD, ssa.OpRISCV64SH2ADD, ssa.OpRISCV64SH3ADD, + ssa.OpRISCV64CZEROEQZ, ssa.OpRISCV64CZERONEZ: r := v.Reg() r1 := v.Args[0].Reg() r2 := v.Args[1].Reg() diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go b/src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go index dc433ff9749150..db27665be54b73 100644 --- a/src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go @@ -520,6 +520,10 @@ func init() { // ====+============================= {name: "FCLASSS", argLength: 1, reg: fpgp, asm: "FCLASSS", typ: "Int64"}, // classify float32 {name: "FCLASSD", argLength: 1, reg: fpgp, asm: "FCLASSD", typ: "Int64"}, // classify float64 + + // RISC-V Integer Conditional (Zicond) operations extension + {name: "CZEROEQZ", argLength: 2, reg: gp21, asm: "CZEROEQZ"}, + {name: "CZERONEZ", argLength: 2, reg: gp21, asm: "CZERONEZ"}, } RISCV64blocks := []blockData{ diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64latelower.rules b/src/cmd/compile/internal/ssa/_gen/RISCV64latelower.rules index 7acaa2f3fec546..2f9b8808920fe7 100644 --- a/src/cmd/compile/internal/ssa/_gen/RISCV64latelower.rules +++ b/src/cmd/compile/internal/ssa/_gen/RISCV64latelower.rules @@ -23,3 +23,33 @@ (SRAI [0] x) => x (SRLI [0] x) => x (SLLI [0] x) => x + +// "Zicond" Extension for Integer Conditional Operations +// (x == 0) ? x : y +(CondSelect x y (SEQZ x)) && buildcfg.GORISCV64 >= 23 => (CZEROEQZ y x) +// (z == 0) ? (x + y) : y +(CondSelect (ADD x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (ADD x (CZERONEZ y z)) +// (z != 0) ? (x + y) : y +(CondSelect (ADD x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (ADD x (CZEROEQZ y z)) +// (z == 0) ? (x - y) : y +(CondSelect (SUB x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (SUB x (CZERONEZ y z)) +// (z != 0) ? (x - y) : y +(CondSelect (SUB x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (SUB x (CZEROEQZ y z)) +// (z == 0) ? (x | y) : y +(CondSelect (OR x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (OR x (CZERONEZ y z)) +// (z != 0) ? (x | y) : y +(CondSelect (OR x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (OR x (CZEROEQZ y z)) +// (z == 0) ? (x ^ y) : y +(CondSelect (XOR x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (XOR x (CZERONEZ y z)) +// (z != 0) ? (x ^ y) : y +(CondSelect (XOR x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (XOR x (CZEROEQZ y z)) +// (z == 0) ? (x & y) : y +(CondSelect (AND x y) x (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (OR (AND x y) (CZEROEQZ x z)) +// (z != 0) ? (x & y) : y +(CondSelect (AND x y) x (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (OR (AND x y) (CZERONEZ x z)) +// (z == 0) ? x : y +(CondSelect x y (SEQZ z)) && buildcfg.GORISCV64 >= 23 => (OR (CZERONEZ x z) (CZEROEQZ y z)) +// (z != 0) ? x : y +(CondSelect x y (SNEZ z)) && buildcfg.GORISCV64 >= 23 => (OR (CZEROEQZ x z) (CZERONEZ y z)) +// Make sure we can rewrite all CondSelects. +(CondSelect x y cond) && buildcfg.GORISCV64 >= 23 => (OR (CZEROEQZ x cond) (CZERONEZ y cond)) diff --git a/src/cmd/compile/internal/ssa/branchelim.go b/src/cmd/compile/internal/ssa/branchelim.go index a7d339cad064ac..66922b7ab09fba 100644 --- a/src/cmd/compile/internal/ssa/branchelim.go +++ b/src/cmd/compile/internal/ssa/branchelim.go @@ -4,7 +4,10 @@ package ssa -import "cmd/internal/src" +import ( + "cmd/internal/src" + "internal/buildcfg" +) // branchelim tries to eliminate branches by // generating CondSelect instructions. @@ -24,6 +27,10 @@ func branchelim(f *Func) { switch f.Config.arch { case "arm64", "ppc64le", "ppc64", "amd64", "wasm", "loong64": // implemented + case "riscv64": + if buildcfg.GORISCV64 < 23 { + return + } default: return } diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index b4aae50b895ff8..76df7d999bee11 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -2648,6 +2648,8 @@ const ( OpRISCV64LoweredFMAXD OpRISCV64FCLASSS OpRISCV64FCLASSD + OpRISCV64CZEROEQZ + OpRISCV64CZERONEZ OpS390XFADDS OpS390XFADD @@ -35662,6 +35664,34 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "CZEROEQZ", + argLen: 2, + asm: riscv.ACZEROEQZ, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + outputs: []outputInfo{ + {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + }, + }, + { + name: "CZERONEZ", + argLen: 2, + asm: riscv.ACZERONEZ, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + outputs: []outputInfo{ + {0, 1006632944}, // X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + }, + }, { name: "FADDS", diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64latelower.go b/src/cmd/compile/internal/ssa/rewriteRISCV64latelower.go index d2c3a8f73df2e9..e7336e4d489b2e 100644 --- a/src/cmd/compile/internal/ssa/rewriteRISCV64latelower.go +++ b/src/cmd/compile/internal/ssa/rewriteRISCV64latelower.go @@ -2,8 +2,12 @@ package ssa +import "internal/buildcfg" + func rewriteValueRISCV64latelower(v *Value) bool { switch v.Op { + case OpCondSelect: + return rewriteValueRISCV64latelower_OpCondSelect(v) case OpRISCV64AND: return rewriteValueRISCV64latelower_OpRISCV64AND(v) case OpRISCV64NOT: @@ -21,6 +25,373 @@ func rewriteValueRISCV64latelower(v *Value) bool { } return false } +func rewriteValueRISCV64latelower_OpCondSelect(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + // match: (CondSelect x y (SEQZ x)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (CZEROEQZ y x) + for { + t := v.Type + x := v_0 + y := v_1 + if v_2.Op != OpRISCV64SEQZ || x != v_2.Args[0] || !(buildcfg.GORISCV64 >= 23) { + break + } + v.reset(OpRISCV64CZEROEQZ) + v.Type = t + v.AddArg2(y, x) + return true + } + // match: (CondSelect (ADD x y) x (SEQZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (ADD x (CZERONEZ y z)) + for { + t := v.Type + if v_0.Op != OpRISCV64ADD { + break + } + _ = 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 + if x != v_1 || v_2.Op != OpRISCV64SEQZ { + continue + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + continue + } + v.reset(OpRISCV64ADD) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v0.AddArg2(y, z) + v.AddArg2(x, v0) + return true + } + break + } + // match: (CondSelect (ADD x y) x (SNEZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (ADD x (CZEROEQZ y z)) + for { + t := v.Type + if v_0.Op != OpRISCV64ADD { + break + } + _ = 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 + if x != v_1 || v_2.Op != OpRISCV64SNEZ { + continue + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + continue + } + v.reset(OpRISCV64ADD) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(y, z) + v.AddArg2(x, v0) + return true + } + break + } + // match: (CondSelect (SUB x y) x (SEQZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (SUB x (CZERONEZ y z)) + for { + t := v.Type + if v_0.Op != OpRISCV64SUB { + break + } + y := v_0.Args[1] + x := v_0.Args[0] + if x != v_1 || v_2.Op != OpRISCV64SEQZ { + break + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + break + } + v.reset(OpRISCV64SUB) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v0.AddArg2(y, z) + v.AddArg2(x, v0) + return true + } + // match: (CondSelect (SUB x y) x (SNEZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (SUB x (CZEROEQZ y z)) + for { + t := v.Type + if v_0.Op != OpRISCV64SUB { + break + } + y := v_0.Args[1] + x := v_0.Args[0] + if x != v_1 || v_2.Op != OpRISCV64SNEZ { + break + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + break + } + v.reset(OpRISCV64SUB) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(y, z) + v.AddArg2(x, v0) + return true + } + // match: (CondSelect (OR x y) x (SEQZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (OR x (CZERONEZ y z)) + for { + t := v.Type + if v_0.Op != OpRISCV64OR { + break + } + _ = 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 + if x != v_1 || v_2.Op != OpRISCV64SEQZ { + continue + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + continue + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v0.AddArg2(y, z) + v.AddArg2(x, v0) + return true + } + break + } + // match: (CondSelect (OR x y) x (SNEZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (OR x (CZEROEQZ y z)) + for { + t := v.Type + if v_0.Op != OpRISCV64OR { + break + } + _ = 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 + if x != v_1 || v_2.Op != OpRISCV64SNEZ { + continue + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + continue + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(y, z) + v.AddArg2(x, v0) + return true + } + break + } + // match: (CondSelect (XOR x y) x (SEQZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (XOR x (CZERONEZ y z)) + for { + t := v.Type + if v_0.Op != OpRISCV64XOR { + break + } + _ = 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 + if x != v_1 || v_2.Op != OpRISCV64SEQZ { + continue + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + continue + } + v.reset(OpRISCV64XOR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v0.AddArg2(y, z) + v.AddArg2(x, v0) + return true + } + break + } + // match: (CondSelect (XOR x y) x (SNEZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (XOR x (CZEROEQZ y z)) + for { + t := v.Type + if v_0.Op != OpRISCV64XOR { + break + } + _ = 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 + if x != v_1 || v_2.Op != OpRISCV64SNEZ { + continue + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + continue + } + v.reset(OpRISCV64XOR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(y, z) + v.AddArg2(x, v0) + return true + } + break + } + // match: (CondSelect (AND x y) x (SEQZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (OR (AND x y) (CZEROEQZ x z)) + for { + t := v.Type + if v_0.Op != OpRISCV64AND { + break + } + _ = 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 + if x != v_1 || v_2.Op != OpRISCV64SEQZ { + continue + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + continue + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64AND, t) + v0.AddArg2(x, y) + v1 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v1.AddArg2(x, z) + v.AddArg2(v0, v1) + return true + } + break + } + // match: (CondSelect (AND x y) x (SNEZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (OR (AND x y) (CZERONEZ x z)) + for { + t := v.Type + if v_0.Op != OpRISCV64AND { + break + } + _ = 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 + if x != v_1 || v_2.Op != OpRISCV64SNEZ { + continue + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + continue + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64AND, t) + v0.AddArg2(x, y) + v1 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v1.AddArg2(x, z) + v.AddArg2(v0, v1) + return true + } + break + } + // match: (CondSelect x y (SEQZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (OR (CZERONEZ x z) (CZEROEQZ y z)) + for { + t := v.Type + x := v_0 + y := v_1 + if v_2.Op != OpRISCV64SEQZ { + break + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + break + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v0.AddArg2(x, z) + v1 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v1.AddArg2(y, z) + v.AddArg2(v0, v1) + return true + } + // match: (CondSelect x y (SNEZ z)) + // cond: buildcfg.GORISCV64 >= 23 + // result: (OR (CZEROEQZ x z) (CZERONEZ y z)) + for { + t := v.Type + x := v_0 + y := v_1 + if v_2.Op != OpRISCV64SNEZ { + break + } + z := v_2.Args[0] + if !(buildcfg.GORISCV64 >= 23) { + break + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(x, z) + v1 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v1.AddArg2(y, z) + v.AddArg2(v0, v1) + return true + } + // match: (CondSelect x y cond) + // cond: buildcfg.GORISCV64 >= 23 + // result: (OR (CZEROEQZ x cond) (CZERONEZ y cond)) + for { + t := v.Type + x := v_0 + y := v_1 + cond := v_2 + if !(buildcfg.GORISCV64 >= 23) { + break + } + v.reset(OpRISCV64OR) + v0 := b.NewValue0(v.Pos, OpRISCV64CZEROEQZ, t) + v0.AddArg2(x, cond) + v1 := b.NewValue0(v.Pos, OpRISCV64CZERONEZ, t) + v1.AddArg2(y, cond) + v.AddArg2(v0, v1) + return true + } + return false +} func rewriteValueRISCV64latelower_OpRISCV64AND(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] diff --git a/test/codegen/zicond.go b/test/codegen/zicond.go new file mode 100644 index 00000000000000..c3c6b65bc972e3 --- /dev/null +++ b/test/codegen/zicond.go @@ -0,0 +1,180 @@ +// asmcheck + +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package codegen + +//go:noinline +func testIfxZero(a, b int) int { + r := b + if a == 0 { + r = a + } + // riscv64/rva23u64:`CZEROEQZ`, -`CZERONEZ` + return r +} + +//go:noinline +func testZicond(a, b int) int { + var c int + if a > b { + c = a + } else { + c = b + } + // riscv64/rva23u64:`CZERONEZ`,`CZEROEQZ` + return c +} + +//go:noinline +func selectIfZero(cond, a, b int) int { + r := a + if cond == 0 { + r = b + } + // riscv64/rva23u64:`CZERONEZ`,`CZEROEQZ`, `OR` + // riscv64/rva23u64:-`SEQZ` + return r +} + +//go:noinline +func testSelectIfNotZero(cond, a, b int) int { + r := a + if cond != 0 { + r = b + } + // riscv64/rva23u64:`CZERONEZ`,`CZEROEQZ`, `OR` + // riscv64/rva23u64:-`SNEZ` + return r +} + +//go:noinline +func testCondAddZero(cond, a, b int) int { + result := a + if cond == 0 { + result = a + b + } + // riscv64/rva23u64:`CZERONEZ`, `ADD` + // riscv64/rva23u64:-`SEQZ`, -`CZEROEQZ`, -`OR` + return result +} + +//go:noinline +func testCondAddNonZero(cond, a, b int) int { + var result int + if cond != 0 { + result = a + b + } else { + result = a + } + // riscv64/rva23u64:`CZEROEQZ`, `ADD` + // riscv64/rva23u64:-`SNEZ`, -`CZERONEZ`, -`OR` + return result +} + +//go:noinline +func testCondSubZero(cond, a, b int) int { + var result int + if cond == 0 { + result = a - b + } else { + result = a + } + // riscv64/rva23u64:`CZERONEZ`, `SUB` + // riscv64/rva23u64:-`SEQZ`, -`CZEROEQZ`, -`OR` + return result +} + +//go:noinline +func testCondSubNonZero(cond, a, b int) int { + var result int + if cond != 0 { + result = a - b + } else { + result = a + } + // riscv64/rva23u64:`CZEROEQZ`, `SUB` + // riscv64/rva23u64:-`SNEZ`, -`CZERONEZ`, -`OR` + return result +} + +//go:noinline +func testCondOrZero(cond, a, b int) int { + var result int + if cond == 0 { + result = a | b + } else { + result = a + } + // riscv64/rva23u64:`CZERONEZ`, `OR` + // riscv64/rva23u64:-`SEQZ`, -`CZEROEQZ` + return result +} + +//go:noinline +func testCondOrNonZero(cond, a, b int) int { + var result int + if cond != 0 { + result = a | b + } else { + result = a + } + // riscv64/rva23u64:`CZEROEQZ`, `OR` + // riscv64/rva23u64:-`SNEZ`, -`CZERONEZ` + return result +} + +//go:noinline +func testCondXorZero(cond, a, b int) int { + var result int + if cond == 0 { + result = a ^ b + } else { + result = a + } + // riscv64/rva23u64:`CZERONEZ`, `XOR` + // riscv64/rva23u64:-`SEQZ`, -`CZEROEQZ`, -`OR` + return result +} + +//go:noinline +func testCondXorNonZero(cond, a, b int) int { + var result int + if cond != 0 { + result = a ^ b + } else { + result = a + } + // riscv64/rva23u64:`CZEROEQZ`, `XOR` + // riscv64/rva23u64:-`SNEZ`, -`CZERONEZ`, -`OR` + return result +} + +//go:noinline +func testCondAndZero(cond, a, b int) int { + var result int + if cond == 0 { + result = a & b + } else { + result = a + } + // riscv64/rva23u64:`CZEROEQZ`, `AND`, `OR` + // riscv64/rva23u64:-`SEQZ`, -`CZERONEZ` + return result +} + +//go:noinline +func testCondAndNonZero(cond, a, b int) int { + var result int + if cond != 0 { + result = a & b + } else { + result = a + } + // riscv64/rva23u64:`CZERONEZ`, `AND`, `OR` + // riscv64/rva23u64:-`SNEZ`, -`CZEROEQZ` + return result +} + \ No newline at end of file From f5f9d07332ea4ccbafa96c8dcfd94a7fa9fef18a Mon Sep 17 00:00:00 2001 From: lxq015 <1824368278@qq.com> Date: Wed, 24 Sep 2025 12:34:15 +0800 Subject: [PATCH 2/3] add tests --- test/codegen/zicond.go | 75 ++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/test/codegen/zicond.go b/test/codegen/zicond.go index c3c6b65bc972e3..788bfe8fa764e2 100644 --- a/test/codegen/zicond.go +++ b/test/codegen/zicond.go @@ -7,47 +7,67 @@ package codegen //go:noinline -func testIfxZero(a, b int) int { - r := b +func testNoZicondUnderRva20u64(a, b int) int { + result := b if a == 0 { - r = a + result = a + } + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + return result +} + +//go:noinline +func testNoZicondUnderRva22u64(a, b int) int { + result := b + if a == 0 { + result = a + } + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + return result +} + +//go:noinline +func testGenZicondUnderRva23u64(a, b int) int { + result := b + if a == 0 { + result = a } // riscv64/rva23u64:`CZEROEQZ`, -`CZERONEZ` - return r + return result } //go:noinline -func testZicond(a, b int) int { - var c int +func testGenZicond(a, b int) int { + var result int if a > b { - c = a + result = a } else { - c = b + result = b } // riscv64/rva23u64:`CZERONEZ`,`CZEROEQZ` - return c + return result } //go:noinline func selectIfZero(cond, a, b int) int { - r := a + result := a if cond == 0 { - r = b + result = b } // riscv64/rva23u64:`CZERONEZ`,`CZEROEQZ`, `OR` // riscv64/rva23u64:-`SEQZ` - return r + return result } //go:noinline func testSelectIfNotZero(cond, a, b int) int { - r := a + result := a if cond != 0 { - r = b + result = b } // riscv64/rva23u64:`CZERONEZ`,`CZEROEQZ`, `OR` // riscv64/rva23u64:-`SNEZ` - return r + return result } //go:noinline @@ -60,7 +80,7 @@ func testCondAddZero(cond, a, b int) int { // riscv64/rva23u64:-`SEQZ`, -`CZEROEQZ`, -`OR` return result } - + //go:noinline func testCondAddNonZero(cond, a, b int) int { var result int @@ -102,11 +122,11 @@ func testCondSubNonZero(cond, a, b int) int { //go:noinline func testCondOrZero(cond, a, b int) int { - var result int - if cond == 0 { + var result int + if cond == 0 { result = a | b - } else { - result = a + } else { + result = a } // riscv64/rva23u64:`CZERONEZ`, `OR` // riscv64/rva23u64:-`SEQZ`, -`CZEROEQZ` @@ -115,16 +135,16 @@ func testCondOrZero(cond, a, b int) int { //go:noinline func testCondOrNonZero(cond, a, b int) int { - var result int - if cond != 0 { + var result int + if cond != 0 { result = a | b - } else { - result = a + } else { + result = a } // riscv64/rva23u64:`CZEROEQZ`, `OR` // riscv64/rva23u64:-`SNEZ`, -`CZERONEZ` return result -} +} //go:noinline func testCondXorZero(cond, a, b int) int { @@ -138,7 +158,7 @@ func testCondXorZero(cond, a, b int) int { // riscv64/rva23u64:-`SEQZ`, -`CZEROEQZ`, -`OR` return result } - + //go:noinline func testCondXorNonZero(cond, a, b int) int { var result int @@ -164,7 +184,7 @@ func testCondAndZero(cond, a, b int) int { // riscv64/rva23u64:-`SEQZ`, -`CZERONEZ` return result } - + //go:noinline func testCondAndNonZero(cond, a, b int) int { var result int @@ -177,4 +197,3 @@ func testCondAndNonZero(cond, a, b int) int { // riscv64/rva23u64:-`SNEZ`, -`CZEROEQZ` return result } - \ No newline at end of file From 58e1e0c7ed56a4a41de8a685f603b4b0f8f7c515 Mon Sep 17 00:00:00 2001 From: lxq015 <1824368278@qq.com> Date: Thu, 25 Sep 2025 16:40:16 +0800 Subject: [PATCH 3/3] move tests in zicond.go to condmove.go --- test/codegen/condmove.go | 228 +++++++++++++++++++++++++++++++++++++++ test/codegen/zicond.go | 199 ---------------------------------- 2 files changed, 228 insertions(+), 199 deletions(-) delete mode 100644 test/codegen/zicond.go diff --git a/test/codegen/condmove.go b/test/codegen/condmove.go index 97be0ced75d19d..8670d0e65c71e3 100644 --- a/test/codegen/condmove.go +++ b/test/codegen/condmove.go @@ -15,6 +15,9 @@ func cmovint(c int) int { // arm64:"CSEL\tLT" // ppc64x:"ISEL\t[$]0" // wasm:"Select" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return x } @@ -26,6 +29,9 @@ func cmovchan(x, y chan int) chan int { // arm64:"CSEL\tNE" // ppc64x:"ISEL\t[$]2" // wasm:"Select" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return x } @@ -37,6 +43,9 @@ func cmovuintptr(x, y uintptr) uintptr { // arm64:"CSNEG\tLS" // ppc64x:"ISEL\t[$]1" // wasm:"Select" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return x } @@ -48,6 +57,9 @@ func cmov32bit(x, y uint32) uint32 { // arm64:"CSNEG\t(LS|HS)" // ppc64x:"ISEL\t[$]1" // wasm:"Select" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return x } @@ -59,6 +71,9 @@ func cmov16bit(x, y uint16) uint16 { // arm64:"CSNEG\t(LS|HS)" // ppc64x:"ISEL\t[$][01]" // wasm:"Select" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return x } @@ -73,6 +88,9 @@ func cmovfloateq(x, y float64) int { // arm64:"CSEL\tEQ" // ppc64x:"ISEL\t[$]2" // wasm:"Select" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return a } @@ -85,6 +103,9 @@ func cmovfloatne(x, y float64) int { // arm64:"CSEL\tNE" // ppc64x:"ISEL\t[$]2" // wasm:"Select" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return a } @@ -112,6 +133,9 @@ func cmovfloatint2(x, y float64) float64 { // arm64:"CSEL\tMI" // ppc64x:"ISEL\t[$]0" // wasm:"Select" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r = r - ldexp(y, rexp-yexp) } return r @@ -127,6 +151,9 @@ func cmovloaded(x [4]int, y int) int { // arm64:"CSEL\tNE" // ppc64x:"ISEL\t[$]2" // wasm:"Select" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR`, -`SNEZ` return y } @@ -139,6 +166,9 @@ func cmovuintptr2(x, y uintptr) uintptr { // arm64:"CSEL\tEQ" // ppc64x:"ISEL\t[$]2" // wasm:"Select" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR`, -`SEQZ` return a } @@ -165,6 +195,9 @@ func cmovinvert1(x, y int64) int64 { y = -y } // amd64:"CMOVQGT" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return y } func cmovinvert2(x, y int64) int64 { @@ -179,6 +212,9 @@ func cmovinvert3(x, y int64) int64 { y = -y } // amd64:"CMOVQEQ" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return y } func cmovinvert4(x, y int64) int64 { @@ -186,6 +222,9 @@ func cmovinvert4(x, y int64) int64 { y = -y } // amd64:"CMOVQNE" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return y } func cmovinvert5(x, y uint64) uint64 { @@ -193,6 +232,9 @@ func cmovinvert5(x, y uint64) uint64 { y = -y } // amd64:"CMOVQCS" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return y } func cmovinvert6(x, y uint64) uint64 { @@ -200,6 +242,9 @@ func cmovinvert6(x, y uint64) uint64 { y = -y } // amd64:"CMOVQLS" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return y } @@ -217,6 +262,9 @@ func cmovstore(a []int, i int, b bool) { i += 42 } // amd64:"CMOVQNE" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` a[i] = 7 } @@ -231,6 +279,9 @@ func cmovinc(cond bool, a, b, c int) { x0 = b + 1 } // arm64:"CSINC\tNE", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r0 = x0 if cond { @@ -239,6 +290,9 @@ func cmovinc(cond bool, a, b, c int) { x1 = a } // arm64:"CSINC\tEQ", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r1 = x1 if cond { @@ -257,6 +311,9 @@ func cmovinv(cond bool, a, b int) { x0 = ^b } // arm64:"CSINV\tNE", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r0 = x0 if cond { @@ -265,6 +322,9 @@ func cmovinv(cond bool, a, b int) { x1 = a } // arm64:"CSINV\tEQ", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r1 = x1 } @@ -277,6 +337,9 @@ func cmovneg(cond bool, a, b, c int) { x0 = -b } // arm64:"CSNEG\tNE", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r0 = x0 if cond { @@ -285,6 +348,9 @@ func cmovneg(cond bool, a, b, c int) { x1 = a } // arm64:"CSNEG\tEQ", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r1 = x1 } @@ -297,6 +363,9 @@ func cmovsetm(cond bool, x int) { x0 = 0 } // arm64:"CSETM\tNE", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r0 = x0 if cond { @@ -305,6 +374,9 @@ func cmovsetm(cond bool, x int) { x1 = -1 } // arm64:"CSETM\tEQ", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r1 = x1 } @@ -317,6 +389,9 @@ func cmovFcmp0(s, t float64, a, b int) { x0 = b + 1 } // arm64:"CSINC\tMI", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r0 = x0 if s <= t { @@ -325,6 +400,9 @@ func cmovFcmp0(s, t float64, a, b int) { x1 = ^b } // arm64:"CSINV\tLS", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r1 = x1 if s > t { @@ -333,6 +411,9 @@ func cmovFcmp0(s, t float64, a, b int) { x2 = -b } // arm64:"CSNEG\tMI", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r2 = x2 if s >= t { @@ -341,6 +422,9 @@ func cmovFcmp0(s, t float64, a, b int) { x3 = 0 } // arm64:"CSETM\tLS", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r3 = x3 if s == t { @@ -349,6 +433,9 @@ func cmovFcmp0(s, t float64, a, b int) { x4 = b + 1 } // arm64:"CSINC\tEQ", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r4 = x4 if s != t { @@ -357,6 +444,9 @@ func cmovFcmp0(s, t float64, a, b int) { x5 = b + 1 } // arm64:"CSINC\tNE", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r5 = x5 } @@ -369,6 +459,9 @@ func cmovFcmp1(s, t float64, a, b int) { x0 = a } // arm64:"CSINC\tPL", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r0 = x0 if s <= t { @@ -377,6 +470,9 @@ func cmovFcmp1(s, t float64, a, b int) { x1 = a } // arm64:"CSINV\tHI", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r1 = x1 if s > t { @@ -385,6 +481,9 @@ func cmovFcmp1(s, t float64, a, b int) { x2 = a } // arm64:"CSNEG\tPL", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r2 = x2 if s >= t { @@ -393,6 +492,9 @@ func cmovFcmp1(s, t float64, a, b int) { x3 = -1 } // arm64:"CSETM\tHI", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r3 = x3 if s == t { @@ -401,6 +503,9 @@ func cmovFcmp1(s, t float64, a, b int) { x4 = a } // arm64:"CSINC\tNE", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r4 = x4 if s != t { @@ -409,6 +514,9 @@ func cmovFcmp1(s, t float64, a, b int) { x5 = a } // arm64:"CSINC\tEQ", -"CSEL" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` r5 = x5 } @@ -418,6 +526,9 @@ func cmovzero1(c bool) int { x = 182 } // loong64:"MASKEQZ", -"MASKNEZ" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return x } @@ -427,6 +538,9 @@ func cmovzero2(c bool) int { x = 182 } // loong64:"MASKNEZ", -"MASKEQZ" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return x } @@ -440,6 +554,9 @@ func cmovzeroreg0(a, b int) int { x = a } // ppc64x:"ISEL\t[$]2, R[0-9]+, R0, R[0-9]+" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return x } @@ -449,6 +566,9 @@ func cmovzeroreg1(a, b int) int { x = 0 } // ppc64x:"ISEL\t[$]2, R0, R[0-9]+, R[0-9]+" + // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` + // riscv64/rva23u64:`CZEROEQZ`, `CZERONEZ`, `OR` return x } @@ -507,3 +627,111 @@ func cmovmathhalveu(a uint, b bool) uint { // wasm:"I64ShrU", -"Select" return a } + +func cmoveAddZero(cond, a, b int) int { + result := a + if cond == 0 { + result = a + b + } + // riscv64/rva23u64:`CZERONEZ`, `ADD`, -`SEQZ`, -`CZEROEQZ`, -`OR` + return result +} + +func cmoveAddNonZero(cond, a, b int) int { + var result int + if cond != 0 { + result = a + b + } else { + result = a + } + // riscv64/rva23u64:`CZEROEQZ`, `ADD`, -`SNEZ`, -`CZERONEZ`, -`OR` + return result +} + +func cmoveSubZero(cond, a, b int) int { + var result int + if cond == 0 { + result = a - b + } else { + result = a + } + // riscv64/rva23u64:`CZERONEZ`, `SUB`, -`SEQZ`, -`CZEROEQZ`, -`OR` + return result +} + +func cmoveSubNonZero(cond, a, b int) int { + var result int + if cond != 0 { + result = a - b + } else { + result = a + } + // riscv64/rva23u64:`CZEROEQZ`, `SUB`, -`SNEZ`, -`CZERONEZ`, -`OR` + return result +} + +func cmoveOrZero(cond, a, b int) int { + var result int + if cond == 0 { + result = a | b + } else { + result = a + } + // riscv64/rva23u64:`CZERONEZ`, `OR`, -`SEQZ`, -`CZEROEQZ` + return result +} + +func cmoveOrNonZero(cond, a, b int) int { + var result int + if cond != 0 { + result = a | b + } else { + result = a + } + // riscv64/rva23u64:`CZEROEQZ`, `OR`, -`SNEZ`, -`CZERONEZ` + return result +} + +func cmoveXorZero(cond, a, b int) int { + var result int + if cond == 0 { + result = a ^ b + } else { + result = a + } + // riscv64/rva23u64:`CZERONEZ`, `XOR`, -`SEQZ`, -`CZEROEQZ`, -`OR` + return result +} + +func cmoveXorNonZero(cond, a, b int) int { + var result int + if cond != 0 { + result = a ^ b + } else { + result = a + } + // riscv64/rva23u64:`CZEROEQZ`, `XOR`, -`SNEZ`, -`CZERONEZ`, -`OR` + return result +} + +func cmoveAndZero(cond, a, b int) int { + var result int + if cond == 0 { + result = a & b + } else { + result = a + } + // riscv64/rva23u64:`CZEROEQZ`, `AND`, `OR`, -`SEQZ`, -`CZERONEZ` + return result +} + +func CondAndNonZero(cond, a, b int) int { + var result int + if cond != 0 { + result = a & b + } else { + result = a + } + // riscv64/rva23u64:`CZERONEZ`, `AND`, `OR`, -`SNEZ`, -`CZEROEQZ` + return result +} diff --git a/test/codegen/zicond.go b/test/codegen/zicond.go deleted file mode 100644 index 788bfe8fa764e2..00000000000000 --- a/test/codegen/zicond.go +++ /dev/null @@ -1,199 +0,0 @@ -// asmcheck - -// Copyright 2025 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package codegen - -//go:noinline -func testNoZicondUnderRva20u64(a, b int) int { - result := b - if a == 0 { - result = a - } - // riscv64/rva20u64:-`CZEROEQZ`, -`CZERONEZ` - return result -} - -//go:noinline -func testNoZicondUnderRva22u64(a, b int) int { - result := b - if a == 0 { - result = a - } - // riscv64/rva22u64:-`CZEROEQZ`, -`CZERONEZ` - return result -} - -//go:noinline -func testGenZicondUnderRva23u64(a, b int) int { - result := b - if a == 0 { - result = a - } - // riscv64/rva23u64:`CZEROEQZ`, -`CZERONEZ` - return result -} - -//go:noinline -func testGenZicond(a, b int) int { - var result int - if a > b { - result = a - } else { - result = b - } - // riscv64/rva23u64:`CZERONEZ`,`CZEROEQZ` - return result -} - -//go:noinline -func selectIfZero(cond, a, b int) int { - result := a - if cond == 0 { - result = b - } - // riscv64/rva23u64:`CZERONEZ`,`CZEROEQZ`, `OR` - // riscv64/rva23u64:-`SEQZ` - return result -} - -//go:noinline -func testSelectIfNotZero(cond, a, b int) int { - result := a - if cond != 0 { - result = b - } - // riscv64/rva23u64:`CZERONEZ`,`CZEROEQZ`, `OR` - // riscv64/rva23u64:-`SNEZ` - return result -} - -//go:noinline -func testCondAddZero(cond, a, b int) int { - result := a - if cond == 0 { - result = a + b - } - // riscv64/rva23u64:`CZERONEZ`, `ADD` - // riscv64/rva23u64:-`SEQZ`, -`CZEROEQZ`, -`OR` - return result -} - -//go:noinline -func testCondAddNonZero(cond, a, b int) int { - var result int - if cond != 0 { - result = a + b - } else { - result = a - } - // riscv64/rva23u64:`CZEROEQZ`, `ADD` - // riscv64/rva23u64:-`SNEZ`, -`CZERONEZ`, -`OR` - return result -} - -//go:noinline -func testCondSubZero(cond, a, b int) int { - var result int - if cond == 0 { - result = a - b - } else { - result = a - } - // riscv64/rva23u64:`CZERONEZ`, `SUB` - // riscv64/rva23u64:-`SEQZ`, -`CZEROEQZ`, -`OR` - return result -} - -//go:noinline -func testCondSubNonZero(cond, a, b int) int { - var result int - if cond != 0 { - result = a - b - } else { - result = a - } - // riscv64/rva23u64:`CZEROEQZ`, `SUB` - // riscv64/rva23u64:-`SNEZ`, -`CZERONEZ`, -`OR` - return result -} - -//go:noinline -func testCondOrZero(cond, a, b int) int { - var result int - if cond == 0 { - result = a | b - } else { - result = a - } - // riscv64/rva23u64:`CZERONEZ`, `OR` - // riscv64/rva23u64:-`SEQZ`, -`CZEROEQZ` - return result -} - -//go:noinline -func testCondOrNonZero(cond, a, b int) int { - var result int - if cond != 0 { - result = a | b - } else { - result = a - } - // riscv64/rva23u64:`CZEROEQZ`, `OR` - // riscv64/rva23u64:-`SNEZ`, -`CZERONEZ` - return result -} - -//go:noinline -func testCondXorZero(cond, a, b int) int { - var result int - if cond == 0 { - result = a ^ b - } else { - result = a - } - // riscv64/rva23u64:`CZERONEZ`, `XOR` - // riscv64/rva23u64:-`SEQZ`, -`CZEROEQZ`, -`OR` - return result -} - -//go:noinline -func testCondXorNonZero(cond, a, b int) int { - var result int - if cond != 0 { - result = a ^ b - } else { - result = a - } - // riscv64/rva23u64:`CZEROEQZ`, `XOR` - // riscv64/rva23u64:-`SNEZ`, -`CZERONEZ`, -`OR` - return result -} - -//go:noinline -func testCondAndZero(cond, a, b int) int { - var result int - if cond == 0 { - result = a & b - } else { - result = a - } - // riscv64/rva23u64:`CZEROEQZ`, `AND`, `OR` - // riscv64/rva23u64:-`SEQZ`, -`CZERONEZ` - return result -} - -//go:noinline -func testCondAndNonZero(cond, a, b int) int { - var result int - if cond != 0 { - result = a & b - } else { - result = a - } - // riscv64/rva23u64:`CZERONEZ`, `AND`, `OR` - // riscv64/rva23u64:-`SNEZ`, -`CZEROEQZ` - return result -}