* [PATCH 3/5] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to 0
2023-07-19 10:11 [PATCH 0/5] Recognize Zicond extension Xiao Zeng
2023-07-19 10:11 ` [PATCH 1/5] [RISC-V] " Xiao Zeng
2023-07-19 10:11 ` [PATCH 2/5] [RISC-V] Generate Zicond instruction for basic semantics Xiao Zeng
@ 2023-07-19 10:11 ` Xiao Zeng
2023-07-25 17:32 ` Jeff Law
` (3 more replies)
2023-07-19 10:11 ` [PATCH 4/5] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to non-zero Xiao Zeng
` (2 subsequent siblings)
5 siblings, 4 replies; 32+ messages in thread
From: Xiao Zeng @ 2023-07-19 10:11 UTC (permalink / raw)
To: gcc-patches
Cc: jeffreyalaw, research_trasio, kito.cheng, zhengyu,
eri-sw-toolchain, Xiao Zeng
This patch completes the recognition of Zicond when the select pattern
with condition eq or neq to 0 (using equality as an example), namely:
1 rd = (rs2 == 0) ? non-imm : 0
2 rd = (rs2 == 0) ? non-imm : non-imm
3 rd = (rs2 == 0) ? reg : non-imm
4 rd = (rs2 == 0) ? reg : reg
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_rtx_costs): IF_THEN_ELSE costs in Zicond.
(riscv_expand_conditional_move): Recognize Zicond.
* config/riscv/riscv.md: Zicond patterns.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/zicond-primitiveSemantics_return_0_imm.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_return_imm_imm.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_return_imm_reg.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_return_reg_reg.c: New test.
---
gcc/config/riscv/riscv.cc | 125 ++++++++++++++++++
gcc/config/riscv/riscv.md | 2 +-
.../zicond-primitiveSemantics_return_0_imm.c | 65 +++++++++
...zicond-primitiveSemantics_return_imm_imm.c | 73 ++++++++++
...zicond-primitiveSemantics_return_imm_reg.c | 65 +++++++++
...zicond-primitiveSemantics_return_reg_reg.c | 65 +++++++++
6 files changed, 394 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_0_imm.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_imm.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_reg.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_reg_reg.c
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 38d8eb2fcf5..7e6b24bd232 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2448,6 +2448,17 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
*total = COSTS_N_INSNS (1);
return true;
}
+ else if (TARGET_ZICOND && outer_code == SET &&
+ ((GET_CODE (XEXP (x, 1)) == REG && XEXP (x, 2) == const0_rtx) ||
+ (GET_CODE (XEXP (x, 2)) == REG && XEXP (x, 1) == const0_rtx) ||
+ (GET_CODE (XEXP (x, 1)) == REG && GET_CODE (XEXP (x, 2)) &&
+ XEXP (x, 1) == XEXP (XEXP (x, 0), 0)) ||
+ (GET_CODE (XEXP (x, 1)) == REG && GET_CODE (XEXP (x, 2)) &&
+ XEXP (x, 2) == XEXP (XEXP (x, 0), 0))))
+ {
+ *total = 0;
+ return true;
+ }
else if (LABEL_REF_P (XEXP (x, 1)) && XEXP (x, 2) == pc_rtx)
{
if (equality_operator (XEXP (x, 0), mode)
@@ -3501,6 +3512,120 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
cond, cons, alt)));
return true;
}
+ else if (TARGET_ZICOND
+ && (code == EQ || code == NE)
+ && GET_MODE_CLASS (mode) == MODE_INT)
+ {
+ need_eq_ne_p = true;
+ /* 0 + imm */
+ if (GET_CODE (cons) == CONST_INT && cons == const0_rtx
+ && GET_CODE (alt) == CONST_INT && alt != const0_rtx)
+ {
+ riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ alt = force_reg (mode, alt);
+ emit_insn (gen_rtx_SET (dest,
+ gen_rtx_IF_THEN_ELSE (mode, cond,
+ cons, alt)));
+ return true;
+ }
+ /* imm + imm */
+ else if (GET_CODE (cons) == CONST_INT && cons != const0_rtx
+ && GET_CODE (alt) == CONST_INT && alt != const0_rtx)
+ {
+ riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ alt = force_reg (mode, alt);
+ rtx temp1 = gen_reg_rtx (mode);
+ rtx temp2 = GEN_INT(-1 * INTVAL (cons));
+ riscv_emit_binary(PLUS, temp1, alt, temp2);
+ emit_insn (gen_rtx_SET (dest,
+ gen_rtx_IF_THEN_ELSE (mode, cond,
+ const0_rtx, alt)));
+ riscv_emit_binary(PLUS, dest, dest, cons);
+ return true;
+ }
+ /* imm + reg */
+ else if (GET_CODE (cons) == CONST_INT && cons != const0_rtx
+ && GET_CODE (alt) == REG)
+ {
+ /* Optimize for register value of 0. */
+ if (op0 == alt && op1 == const0_rtx)
+ {
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ cons = force_reg (mode, cons);
+ emit_insn (gen_rtx_SET (dest,
+ gen_rtx_IF_THEN_ELSE (mode, cond,
+ cons, alt)));
+ return true;
+ }
+ riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ rtx temp1 = gen_reg_rtx (mode);
+ rtx temp2 = GEN_INT(-1 * INTVAL (cons));
+ riscv_emit_binary(PLUS, temp1, alt, temp2);
+ emit_insn (gen_rtx_SET (dest,
+ gen_rtx_IF_THEN_ELSE (mode, cond,
+ const0_rtx, alt)));
+ riscv_emit_binary(PLUS, dest, dest, cons);
+ return true;
+ }
+ /* imm + 0 */
+ else if (GET_CODE (cons) == CONST_INT && cons != const0_rtx
+ && GET_CODE (alt) == CONST_INT && alt == const0_rtx)
+ {
+ riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ cons = force_reg (mode, cons);
+ emit_insn (gen_rtx_SET (dest,
+ gen_rtx_IF_THEN_ELSE (mode, cond,
+ cons, alt)));
+ return true;
+ }
+ /* reg + imm */
+ else if (GET_CODE (cons) == REG
+ && GET_CODE (alt) == CONST_INT && alt != const0_rtx)
+ {
+ /* Optimize for register value of 0. */
+ if (op0 == cons && op1 == const0_rtx)
+ {
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ alt = force_reg (mode, alt);
+ emit_insn (gen_rtx_SET (dest,
+ gen_rtx_IF_THEN_ELSE (mode, cond,
+ cons, alt)));
+ return true;
+ }
+ riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ rtx temp1 = gen_reg_rtx (mode);
+ rtx temp2 = GEN_INT(-1 * INTVAL (alt));
+ riscv_emit_binary(PLUS, temp1, cons, temp2);
+ emit_insn (gen_rtx_SET (dest,
+ gen_rtx_IF_THEN_ELSE (mode, cond,
+ temp1, const0_rtx)));
+ riscv_emit_binary(PLUS, dest, dest, alt);
+ return true;
+ }
+ /* reg + reg */
+ else if (GET_CODE (cons) == REG && GET_CODE (alt) == REG)
+ {
+ rtx reg1 = gen_reg_rtx (mode);
+ rtx reg2 = gen_reg_rtx (mode);
+ riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
+ rtx cond1 = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ rtx cond2 = gen_rtx_fmt_ee (code == NE ? EQ : NE,
+ GET_MODE (op0), op0, op1);
+ emit_insn (gen_rtx_SET (reg2,
+ gen_rtx_IF_THEN_ELSE (mode, cond2,
+ const0_rtx, cons)));
+ emit_insn (gen_rtx_SET (reg1,
+ gen_rtx_IF_THEN_ELSE (mode, cond1,
+ const0_rtx, alt)));
+ riscv_emit_binary(IOR, dest, reg1, reg2);
+ return true;
+ }
+ }
return false;
}
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 6b8c2e8e268..b4147c7a79c 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2484,7 +2484,7 @@
(if_then_else:GPR (match_operand 1 "comparison_operator")
(match_operand:GPR 2 "reg_or_0_operand")
(match_operand:GPR 3 "sfb_alu_operand")))]
- "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV"
+ "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND"
{
if (riscv_expand_conditional_move (operands[0], operands[1],
operands[2], operands[3]))
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_0_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_0_imm.c
new file mode 100644
index 00000000000..4948558a187
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_0_imm.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0"} } */
+
+long primitiveSemantics_return_0_imm_00(long a, long b) {
+ return a == 0 ? 0 : 3;
+}
+
+long primitiveSemantics_return_0_imm_01(long a, long b) {
+ return a != 0 ? 0 : 3;
+}
+
+long primitiveSemantics_return_0_imm_02(long a, long b) {
+ return a == 0 ? 3 : 0;
+}
+
+long primitiveSemantics_return_0_imm_03(long a, long b) {
+ return a != 0 ? 3 : 0;
+}
+
+long primitiveSemantics_return_0_imm_04(long a, long b) {
+ if (a)
+ b = 0;
+ else
+ b = 3;
+ return b;
+}
+
+long primitiveSemantics_return_0_imm_05(long a, long b) {
+ if (!a)
+ b = 0;
+ else
+ b = 3;
+ return b;
+}
+
+int primitiveSemantics_return_0_imm_06(int a, int b) { return a == 0 ? 0 : 3; }
+
+int primitiveSemantics_return_0_imm_07(int a, int b) { return a != 0 ? 0 : 3; }
+
+int primitiveSemantics_return_0_imm_08(int a, int b) { return a == 0 ? 3 : 0; }
+
+int primitiveSemantics_return_0_imm_09(int a, int b) { return a != 0 ? 3 : 0; }
+
+int primitiveSemantics_return_0_imm_10(int a, int b) {
+ if (a)
+ b = 0;
+ else
+ b = 3;
+ return b;
+}
+
+int primitiveSemantics_return_0_imm_11(int a, int b) {
+ if (!a)
+ b = 0;
+ else
+ b = 3;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_imm.c
new file mode 100644
index 00000000000..ebdca521373
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_imm.c
@@ -0,0 +1,73 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */
+
+long primitiveSemantics_return_imm_imm_00(long a, long b) {
+ return a == 0 ? 4 : 6;
+}
+
+long primitiveSemantics_return_imm_imm_01(long a, long b) {
+ return a != 0 ? 4 : 6;
+}
+
+long primitiveSemantics_return_imm_imm_02(long a, long b) {
+ return a == 0 ? 6 : 4;
+}
+
+long primitiveSemantics_return_imm_imm_03(long a, long b) {
+ return a != 0 ? 6 : 4;
+}
+
+long primitiveSemantics_return_imm_imm_04(long a, long b) {
+ if (a)
+ b = 4;
+ else
+ b = 6;
+ return b;
+}
+
+long primitiveSemantics_return_imm_imm_05(long a, long b) {
+ if (!a)
+ b = 4;
+ else
+ b = 6;
+ return b;
+}
+
+int primitiveSemantics_return_imm_imm_06(int a, int b) {
+ return a == 0 ? 4 : 6;
+}
+
+int primitiveSemantics_return_imm_imm_07(int a, int b) {
+ return a != 0 ? 4 : 6;
+}
+
+int primitiveSemantics_return_imm_imm_08(int a, int b) {
+ return a == 0 ? 6 : 4;
+}
+
+int primitiveSemantics_return_imm_imm_09(int a, int b) {
+ return a != 0 ? 6 : 4;
+}
+
+int primitiveSemantics_return_imm_imm_10(int a, int b) {
+ if (a)
+ b = 4;
+ else
+ b = 6;
+ return b;
+}
+
+int primitiveSemantics_return_imm_imm_11(int a, int b) {
+ if (!a)
+ b = 4;
+ else
+ b = 6;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_reg.c
new file mode 100644
index 00000000000..12c351dbc16
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_imm_reg.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */
+
+long primitiveSemantics_return_imm_reg_00(long a, long b) {
+ return a == 0 ? 1 : b;
+}
+
+long primitiveSemantics_return_imm_reg_01(long a, long b) {
+ return a != 0 ? 1 : b;
+}
+
+long primitiveSemantics_return_imm_reg_02(long a, long b) {
+ return a == 0 ? b : 1;
+}
+
+long primitiveSemantics_return_imm_reg_03(long a, long b) {
+ return a != 0 ? b : 1;
+}
+
+long primitiveSemantics_return_imm_reg_04(long a, long b) {
+ if (a)
+ b = 1;
+ return b;
+}
+
+long primitiveSemantics_return_imm_reg_05(long a, long b) {
+ if (!a)
+ b = 1;
+ return b;
+}
+
+int primitiveSemantics_return_imm_reg_06(int a, int b) {
+ return a == 0 ? 1 : b;
+}
+
+int primitiveSemantics_return_imm_reg_07(int a, int b) {
+ return a != 0 ? 1 : b;
+}
+
+int primitiveSemantics_return_imm_reg_08(int a, int b) {
+ return a == 0 ? b : 1;
+}
+
+int primitiveSemantics_return_imm_reg_09(int a, int b) {
+ return a != 0 ? b : 1;
+}
+
+int primitiveSemantics_return_imm_reg_10(int a, int b) {
+ if (a)
+ b = 1;
+ return b;
+}
+
+int primitiveSemantics_return_imm_reg_11(int a, int b) {
+ if (!a)
+ b = 1;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_reg_reg.c
new file mode 100644
index 00000000000..4708afa645b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_return_reg_reg.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */
+
+long primitiveSemantics_return_reg_reg_00(long a, long b, long c) {
+ return a == 0 ? c : b;
+}
+
+long primitiveSemantics_return_reg_reg_01(long a, long b, long c) {
+ return a != 0 ? c : b;
+}
+
+long primitiveSemantics_return_reg_reg_02(long a, long b, long c) {
+ return a == 0 ? b : c;
+}
+
+long primitiveSemantics_return_reg_reg_03(long a, long b, long c) {
+ return a != 0 ? b : c;
+}
+
+long primitiveSemantics_return_reg_reg_04(long a, long b, long c) {
+ if (a)
+ b = c;
+ return b;
+}
+
+long primitiveSemantics_return_reg_reg_05(long a, long b, long c) {
+ if (!a)
+ b = c;
+ return b;
+}
+
+int primitiveSemantics_return_reg_reg_06(int a, int b, int c) {
+ return a == 0 ? c : b;
+}
+
+int primitiveSemantics_return_reg_reg_07(int a, int b, int c) {
+ return a != 0 ? c : b;
+}
+
+int primitiveSemantics_return_reg_reg_08(int a, int b, int c) {
+ return a == 0 ? b : c;
+}
+
+int primitiveSemantics_return_reg_reg_09(int a, int b, int c) {
+ return a != 0 ? b : c;
+}
+
+int primitiveSemantics_return_reg_reg_10(int a, int b, int c) {
+ if (a)
+ b = c;
+ return b;
+}
+
+int primitiveSemantics_return_reg_reg_11(int a, int b, int c) {
+ if (!a)
+ b = c;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 12 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 12 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
--
2.17.1
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 4/5] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to non-zero
2023-07-19 10:11 [PATCH 0/5] Recognize Zicond extension Xiao Zeng
` (2 preceding siblings ...)
2023-07-19 10:11 ` [PATCH 3/5] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to 0 Xiao Zeng
@ 2023-07-19 10:11 ` Xiao Zeng
2023-08-07 17:36 ` Jeff Law
2023-07-19 10:11 ` [PATCH 5/5] [RISC-V] Generate Zicond instruction for conditional execution Xiao Zeng
2023-07-25 17:51 ` [PATCH 0/5] Recognize Zicond extension Jeff Law
5 siblings, 1 reply; 32+ messages in thread
From: Xiao Zeng @ 2023-07-19 10:11 UTC (permalink / raw)
To: gcc-patches
Cc: jeffreyalaw, research_trasio, kito.cheng, zhengyu,
eri-sw-toolchain, Xiao Zeng
This patch completes the recognition of Zicond when the select pattern with
condition eq or neq to non-zero (using equality as an example), namely:
1 rd = (rs2 == non-imm) ? 0 : rs1
2 rd = (rs2 == reg) ? 0 : rs1
At the same time, more Zicond non basic semantic test cases have been added.
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_expand_conditional_move): Recognize Zicond.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/zicond-primitiveSemantics_compare_imm.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_0_imm.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_compare_reg.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_0_imm.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c: New test.
* gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c: New test.
---
gcc/config/riscv/riscv.cc | 16 ++++
.../zicond-primitiveSemantics_compare_imm.c | 57 ++++++++++++++
...mitiveSemantics_compare_imm_return_0_imm.c | 73 ++++++++++++++++++
...tiveSemantics_compare_imm_return_imm_imm.c | 73 ++++++++++++++++++
...tiveSemantics_compare_imm_return_imm_reg.c | 65 ++++++++++++++++
...tiveSemantics_compare_imm_return_reg_reg.c | 65 ++++++++++++++++
.../zicond-primitiveSemantics_compare_reg.c | 65 ++++++++++++++++
...mitiveSemantics_compare_reg_return_0_imm.c | 73 ++++++++++++++++++
...tiveSemantics_compare_reg_return_imm_imm.c | 73 ++++++++++++++++++
...tiveSemantics_compare_reg_return_imm_reg.c | 65 ++++++++++++++++
...tiveSemantics_compare_reg_return_reg_reg.c | 77 +++++++++++++++++++
11 files changed, 702 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_0_imm.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_0_imm.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 7e6b24bd232..9450457e613 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3625,6 +3625,22 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
riscv_emit_binary(IOR, dest, reg1, reg2);
return true;
}
+ /* For complex semantics of comparison value.
+ reg + 0 or 0 + reg */
+ else if ((GET_CODE (cons) == REG &&
+ GET_CODE (alt) == CONST_INT &&
+ alt == const0_rtx)
+ || (GET_CODE (alt) == REG &&
+ GET_CODE (cons) == CONST_INT &&
+ cons == const0_rtx))
+ {
+ riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ emit_insn (gen_rtx_SET (dest,
+ gen_rtx_IF_THEN_ELSE (mode, cond,
+ cons, alt)));
+ return true;
+ }
}
return false;
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm.c
new file mode 100644
index 00000000000..6de50039c31
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm.c
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0"} } */
+
+long primitiveSemantics_compare_imm_00(long a, long b) {
+ return a == 2 ? 0 : b;
+}
+
+long primitiveSemantics_compare_imm_01(long a, long b) {
+ return a != 2 ? 0 : b;
+}
+
+long primitiveSemantics_compare_imm_02(long a, long b) {
+ return a == 2 ? b : 0;
+}
+
+long primitiveSemantics_compare_imm_03(long a, long b) {
+ return a != 2 ? b : 0;
+}
+
+long primitiveSemantics_compare_imm_04(long a, long b) {
+ if (a == 2)
+ b = 0;
+ return b;
+}
+
+long primitiveSemantics_compare_imm_05(long a, long b) {
+ if (!(a == 2))
+ b = 0;
+ return b;
+}
+
+int primitiveSemantics_compare_imm_06(int a, int b) { return a == 2 ? 0 : b; }
+
+int primitiveSemantics_compare_imm_07(int a, int b) { return a != 2 ? 0 : b; }
+
+int primitiveSemantics_compare_imm_08(int a, int b) { return a == 2 ? b : 0; }
+
+int primitiveSemantics_compare_imm_09(int a, int b) { return a != 2 ? b : 0; }
+
+int primitiveSemantics_compare_imm_10(int a, int b) {
+ if ((a == 2))
+ b = 0;
+ return b;
+}
+
+int primitiveSemantics_compare_imm_11(int a, int b) {
+ if (!(a == 2))
+ b = 0;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_0_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_0_imm.c
new file mode 100644
index 00000000000..b1e7359e802
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_0_imm.c
@@ -0,0 +1,73 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */
+
+long primitiveSemantics_compare_imm_return_0_imm_00(long a, long b) {
+ return a == 2 ? 0 : 5;
+}
+
+long primitiveSemantics_compare_imm_return_0_imm_01(long a, long b) {
+ return a != 2 ? 0 : 5;
+}
+
+long primitiveSemantics_compare_imm_return_0_imm_02(long a, long b) {
+ return a == 2 ? 5 : 0;
+}
+
+long primitiveSemantics_compare_imm_return_0_imm_03(long a, long b) {
+ return a != 2 ? 5 : 0;
+}
+
+long primitiveSemantics_compare_imm_return_0_imm_04(long a, long b) {
+ if (a == 2)
+ b = 0;
+ else
+ b = 5;
+ return b;
+}
+
+long primitiveSemantics_compare_imm_return_0_imm_05(long a, long b) {
+ if (!(a == 2))
+ b = 0;
+ else
+ b = 5;
+ return b;
+}
+
+int primitiveSemantics_compare_imm_return_0_imm_06(int a, int b) {
+ return a == 2 ? 0 : 5;
+}
+
+int primitiveSemantics_compare_imm_return_0_imm_07(int a, int b) {
+ return a != 2 ? 0 : 5;
+}
+
+int primitiveSemantics_compare_imm_return_0_imm_08(int a, int b) {
+ return a == 2 ? 5 : 0;
+}
+
+int primitiveSemantics_compare_imm_return_0_imm_09(int a, int b) {
+ return a != 2 ? 5 : 0;
+}
+
+int primitiveSemantics_compare_imm_return_0_imm_10(int a, int b) {
+ if ((a == 2))
+ b = 0;
+ else
+ b = 5;
+ return b;
+}
+
+int primitiveSemantics_compare_imm_return_0_imm_11(int a, int b) {
+ if (!(a == 2))
+ b = 0;
+ else
+ b = 5;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
new file mode 100644
index 00000000000..bc503e6eafb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
@@ -0,0 +1,73 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */
+
+long primitiveSemantics_compare_imm_return_imm_imm_00(long a, long b) {
+ return a == 2 ? 7 : 4;
+}
+
+long primitiveSemantics_compare_imm_return_imm_imm_01(long a, long b) {
+ return a != 2 ? 7 : 4;
+}
+
+long primitiveSemantics_compare_imm_return_imm_imm_02(long a, long b) {
+ return a == 2 ? 7 : 4;
+}
+
+long primitiveSemantics_compare_imm_return_imm_imm_03(long a, long b) {
+ return a != 2 ? 7 : 4;
+}
+
+long primitiveSemantics_compare_imm_return_imm_imm_04(long a, long b) {
+ if (a == 2)
+ b = 7;
+ else
+ b = 4;
+ return b;
+}
+
+long primitiveSemantics_compare_imm_return_imm_imm_05(long a, long b) {
+ if (!(a == 2))
+ b = 7;
+ else
+ b = 4;
+ return b;
+}
+
+int primitiveSemantics_compare_imm_return_imm_imm_06(int a, int b) {
+ return a == 2 ? 7 : 4;
+}
+
+int primitiveSemantics_compare_imm_return_imm_imm_07(int a, int b) {
+ return a != 2 ? 7 : 4;
+}
+
+int primitiveSemantics_compare_imm_return_imm_imm_08(int a, int b) {
+ return a == 2 ? 7 : 4;
+}
+
+int primitiveSemantics_compare_imm_return_imm_imm_09(int a, int b) {
+ return a != 2 ? 7 : 4;
+}
+
+int primitiveSemantics_compare_imm_return_imm_imm_10(int a, int b) {
+ if ((a == 2))
+ b = 7;
+ else
+ b = 4;
+ return b;
+}
+
+int primitiveSemantics_compare_imm_return_imm_imm_11(int a, int b) {
+ if (!(a == 2))
+ b = 7;
+ else
+ b = 4;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
new file mode 100644
index 00000000000..2bcad7a51d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */
+
+long primitiveSemantics_compare_imm_return_imm_reg_00(long a, long b) {
+ return a == 2 ? 3 : b;
+}
+
+long primitiveSemantics_compare_imm_return_imm_reg_01(long a, long b) {
+ return a != 2 ? 3 : b;
+}
+
+long primitiveSemantics_compare_imm_return_imm_reg_02(long a, long b) {
+ return a == 2 ? b : 3;
+}
+
+long primitiveSemantics_compare_imm_return_imm_reg_03(long a, long b) {
+ return a != 2 ? b : 3;
+}
+
+long primitiveSemantics_compare_imm_return_imm_reg_04(long a, long b) {
+ if (a == 2)
+ b = 3;
+ return b;
+}
+
+long primitiveSemantics_compare_imm_return_imm_reg_05(long a, long b) {
+ if (!(a == 2))
+ b = 3;
+ return b;
+}
+
+int primitiveSemantics_compare_imm_return_imm_reg_06(int a, int b) {
+ return a == 2 ? 3 : b;
+}
+
+int primitiveSemantics_compare_imm_return_imm_reg_07(int a, int b) {
+ return a != 2 ? 3 : b;
+}
+
+int primitiveSemantics_compare_imm_return_imm_reg_08(int a, int b) {
+ return a == 2 ? b : 3;
+}
+
+int primitiveSemantics_compare_imm_return_imm_reg_09(int a, int b) {
+ return a != 2 ? b : 3;
+}
+
+int primitiveSemantics_compare_imm_return_imm_reg_10(int a, int b) {
+ if ((a == 2))
+ b = 3;
+ return b;
+}
+
+int primitiveSemantics_compare_imm_return_imm_reg_11(int a, int b) {
+ if (!(a == 2))
+ b = 3;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
new file mode 100644
index 00000000000..e5d12992dc7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */
+
+long primitiveSemantics_compare_imm_return_reg_reg_00(long a, long b, long c) {
+ return a == 2 ? c : b;
+}
+
+long primitiveSemantics_compare_imm_return_reg_reg_01(long a, long b, long c) {
+ return a != 2 ? c : b;
+}
+
+long primitiveSemantics_compare_imm_return_reg_reg_02(long a, long b, long c) {
+ return a == 2 ? b : c;
+}
+
+long primitiveSemantics_compare_imm_return_reg_reg_03(long a, long b, long c) {
+ return a != 2 ? b : c;
+}
+
+long primitiveSemantics_compare_imm_return_reg_reg_04(long a, long b, long c) {
+ if (a == 2)
+ b = c;
+ return b;
+}
+
+long primitiveSemantics_compare_imm_return_reg_reg_05(long a, long b, long c) {
+ if (!(a == 2))
+ b = c;
+ return b;
+}
+
+int primitiveSemantics_compare_imm_return_reg_reg_06(int a, int b, int c) {
+ return a == 2 ? c : b;
+}
+
+int primitiveSemantics_compare_imm_return_reg_reg_07(int a, int b, int c) {
+ return a != 2 ? c : b;
+}
+
+int primitiveSemantics_compare_imm_return_reg_reg_08(int a, int b, int c) {
+ return a == 2 ? b : c;
+}
+
+int primitiveSemantics_compare_imm_return_reg_reg_09(int a, int b, int c) {
+ return a != 2 ? b : c;
+}
+
+int primitiveSemantics_compare_imm_return_reg_reg_10(int a, int b, int c) {
+ if ((a == 2))
+ b = c;
+ return b;
+}
+
+int primitiveSemantics_compare_imm_return_reg_reg_11(int a, int b, int c) {
+ if (!(a == 2))
+ b = c;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 12 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 12 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg.c
new file mode 100644
index 00000000000..072ae2a26ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0"} } */
+
+long primitiveSemantics_compare_reg_00(long a, long b, long c) {
+ return a == c ? 0 : b;
+}
+
+long primitiveSemantics_compare_reg_01(long a, long b, long c) {
+ return a != c ? 0 : b;
+}
+
+long primitiveSemantics_compare_reg_02(long a, long b, long c) {
+ return a == c ? b : 0;
+}
+
+long primitiveSemantics_compare_reg_03(long a, long b, long c) {
+ return a != c ? b : 0;
+}
+
+long primitiveSemantics_compare_reg_04(long a, long b, long c) {
+ if (a == c)
+ b = 0;
+ return b;
+}
+
+long primitiveSemantics_compare_reg_05(long a, long b, long c) {
+ if (!(a == c))
+ b = 0;
+ return b;
+}
+
+int primitiveSemantics_compare_reg_06(int a, int b, int c) {
+ return a == c ? 0 : b;
+}
+
+int primitiveSemantics_compare_reg_07(int a, int b, int c) {
+ return a != c ? 0 : b;
+}
+
+int primitiveSemantics_compare_reg_08(int a, int b, int c) {
+ return a == c ? b : 0;
+}
+
+int primitiveSemantics_compare_reg_09(int a, int b, int c) {
+ return a != c ? b : 0;
+}
+
+int primitiveSemantics_compare_reg_10(int a, int b, int c) {
+ if ((a == c))
+ b = 0;
+ return b;
+}
+
+int primitiveSemantics_compare_reg_11(int a, int b, int c) {
+ if (!(a == c))
+ b = 0;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_0_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_0_imm.c
new file mode 100644
index 00000000000..66c7bcb9067
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_0_imm.c
@@ -0,0 +1,73 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */
+
+long primitiveSemantics_compare_reg_return_0_imm_00(long a, long b, long c) {
+ return a == c ? 0 : 9;
+}
+
+long primitiveSemantics_compare_reg_return_0_imm_01(long a, long b, long c) {
+ return a != c ? 0 : 9;
+}
+
+long primitiveSemantics_compare_reg_return_0_imm_02(long a, long b, long c) {
+ return a == c ? 9 : 0;
+}
+
+long primitiveSemantics_compare_reg_return_0_imm_03(long a, long b, long c) {
+ return a != c ? 9 : 0;
+}
+
+long primitiveSemantics_compare_reg_return_0_imm_04(long a, long b, long c) {
+ if (a == c)
+ b = 0;
+ else
+ b = 9;
+ return b;
+}
+
+long primitiveSemantics_compare_reg_return_0_imm_05(long a, long b, long c) {
+ if (!(a == c))
+ b = 0;
+ else
+ b = 9;
+ return b;
+}
+
+int primitiveSemantics_compare_reg_return_0_imm_06(int a, int b, int c) {
+ return a == c ? 0 : 9;
+}
+
+int primitiveSemantics_compare_reg_return_0_imm_07(int a, int b, int c) {
+ return a != c ? 0 : 9;
+}
+
+int primitiveSemantics_compare_reg_return_0_imm_08(int a, int b, int c) {
+ return a == c ? 9 : 0;
+}
+
+int primitiveSemantics_compare_reg_return_0_imm_09(int a, int b, int c) {
+ return a != c ? 9 : 0;
+}
+
+int primitiveSemantics_compare_reg_return_0_imm_10(int a, int b, int c) {
+ if ((a == c))
+ b = 0;
+ else
+ b = 9;
+ return b;
+}
+
+int primitiveSemantics_compare_reg_return_0_imm_11(int a, int b, int c) {
+ if (!(a == c))
+ b = 0;
+ else
+ b = 9;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
new file mode 100644
index 00000000000..055ca4833e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
@@ -0,0 +1,73 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */
+
+long primitiveSemantics_compare_reg_return_imm_imm_00(long a, long b, long c) {
+ return a == c ? 7 : 4;
+}
+
+long primitiveSemantics_compare_reg_return_imm_imm_01(long a, long b, long c) {
+ return a != c ? 7 : 4;
+}
+
+long primitiveSemantics_compare_reg_return_imm_imm_02(long a, long b, long c) {
+ return a == c ? 7 : 4;
+}
+
+long primitiveSemantics_compare_reg_return_imm_imm_03(long a, long b, long c) {
+ return a != c ? 7 : 4;
+}
+
+long primitiveSemantics_compare_reg_return_imm_imm_04(long a, long b, long c) {
+ if (a == c)
+ b = 7;
+ else
+ b = 4;
+ return b;
+}
+
+long primitiveSemantics_compare_reg_return_imm_imm_05(long a, long b, long c) {
+ if (!(a == c))
+ b = 7;
+ else
+ b = 4;
+ return b;
+}
+
+int primitiveSemantics_compare_reg_return_imm_imm_06(int a, int b, int c) {
+ return a == c ? 7 : 4;
+}
+
+int primitiveSemantics_compare_reg_return_imm_imm_07(int a, int b, int c) {
+ return a != c ? 7 : 4;
+}
+
+int primitiveSemantics_compare_reg_return_imm_imm_08(int a, int b, int c) {
+ return a == c ? 7 : 4;
+}
+
+int primitiveSemantics_compare_reg_return_imm_imm_09(int a, int b, int c) {
+ return a != c ? 7 : 4;
+}
+
+int primitiveSemantics_compare_reg_return_imm_imm_10(int a, int b, int c) {
+ if ((a == c))
+ b = 7;
+ else
+ b = 4;
+ return b;
+}
+
+int primitiveSemantics_compare_reg_return_imm_imm_11(int a, int b, int c) {
+ if (!(a == c))
+ b = 7;
+ else
+ b = 4;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
new file mode 100644
index 00000000000..85a68bd946f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */
+
+long primitiveSemantics_compare_reg_return_imm_reg_00(long a, long b, long c) {
+ return a == c ? 10 : b;
+}
+
+long primitiveSemantics_compare_reg_return_imm_reg_01(long a, long b, long c) {
+ return a != c ? 10 : b;
+}
+
+long primitiveSemantics_compare_reg_return_imm_reg_02(long a, long b, long c) {
+ return a == c ? b : 10;
+}
+
+long primitiveSemantics_compare_reg_return_imm_reg_03(long a, long b, long c) {
+ return a != c ? b : 10;
+}
+
+long primitiveSemantics_compare_reg_return_imm_reg_04(long a, long b, long c) {
+ if (a == c)
+ b = 10;
+ return b;
+}
+
+long primitiveSemantics_compare_reg_return_imm_reg_05(long a, long b, long c) {
+ if (!(a == c))
+ b = 10;
+ return b;
+}
+
+int primitiveSemantics_compare_reg_return_imm_reg_06(int a, int b, int c) {
+ return a == c ? 10 : b;
+}
+
+int primitiveSemantics_compare_reg_return_imm_reg_07(int a, int b, int c) {
+ return a != c ? 10 : b;
+}
+
+int primitiveSemantics_compare_reg_return_imm_reg_08(int a, int b, int c) {
+ return a == c ? b : 10;
+}
+
+int primitiveSemantics_compare_reg_return_imm_reg_09(int a, int b, int c) {
+ return a != c ? b : 10;
+}
+
+int primitiveSemantics_compare_reg_return_imm_reg_10(int a, int b, int c) {
+ if ((a == c))
+ b = 10;
+ return b;
+}
+
+int primitiveSemantics_compare_reg_return_imm_reg_11(int a, int b, int c) {
+ if (!(a == c))
+ b = 10;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
new file mode 100644
index 00000000000..d6d5d9e7bfa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
@@ -0,0 +1,77 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Os"} } */
+
+long primitiveSemantics_compare_reg_return_reg_reg_00(long a, long b, long c,
+ long d) {
+ return a == c ? d : b;
+}
+
+long primitiveSemantics_compare_reg_return_reg_reg_01(long a, long b, long c,
+ long d) {
+ return a != c ? d : b;
+}
+
+long primitiveSemantics_compare_reg_return_reg_reg_02(long a, long b, long c,
+ long d) {
+ return a == c ? b : d;
+}
+
+long primitiveSemantics_compare_reg_return_reg_reg_03(long a, long b, long c,
+ long d) {
+ return a != c ? b : d;
+}
+
+long primitiveSemantics_compare_reg_return_reg_reg_04(long a, long b, long c,
+ long d) {
+ if (a == c)
+ b = d;
+ return b;
+}
+
+long primitiveSemantics_compare_reg_return_reg_reg_05(long a, long b, long c,
+ long d) {
+ if (!(a == c))
+ b = d;
+ return b;
+}
+
+int primitiveSemantics_compare_reg_return_reg_reg_06(int a, int b, int c,
+ int d) {
+ return a == c ? d : b;
+}
+
+int primitiveSemantics_compare_reg_return_reg_reg_07(int a, int b, int c,
+ int d) {
+ return a != c ? d : b;
+}
+
+int primitiveSemantics_compare_reg_return_reg_reg_08(int a, int b, int c,
+ int d) {
+ return a == c ? b : d;
+}
+
+int primitiveSemantics_compare_reg_return_reg_reg_09(int a, int b, int c,
+ int d) {
+ return a != c ? b : d;
+}
+
+int primitiveSemantics_compare_reg_return_reg_reg_10(int a, int b, int c,
+ int d) {
+ if ((a == c))
+ b = d;
+ return b;
+}
+
+int primitiveSemantics_compare_reg_return_reg_reg_11(int a, int b, int c,
+ int d) {
+ if (!(a == c))
+ b = d;
+ return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 12 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 12 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
--
2.17.1
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 5/5] [RISC-V] Generate Zicond instruction for conditional execution
2023-07-19 10:11 [PATCH 0/5] Recognize Zicond extension Xiao Zeng
` (3 preceding siblings ...)
2023-07-19 10:11 ` [PATCH 4/5] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to non-zero Xiao Zeng
@ 2023-07-19 10:11 ` Xiao Zeng
2023-07-25 17:51 ` [PATCH 0/5] Recognize Zicond extension Jeff Law
5 siblings, 0 replies; 32+ messages in thread
From: Xiao Zeng @ 2023-07-19 10:11 UTC (permalink / raw)
To: gcc-patches
Cc: jeffreyalaw, research_trasio, kito.cheng, zhengyu,
eri-sw-toolchain, Xiao Zeng
This patch completes the recognition of conditional execution
(using equality as an example), namely:
1 rd = (rc == 0) ? (rs1 arith_op rs2) : rs1
Here, arith_op represents the arithmetic operation symbol, which has 8
possibilities: + - | ^ << >>(Shift Right Arithmetic) >>(Shift Right Logical) &
At the same time, more Zicond non basic conditional execution test cases have
also been added, namely:
2 rd = (rc == 0) ? (rs1 arith_op non-imm) : rs1
3 rd = (rc == non-imm) ? (rs1 arith_op rs2) : rs1
4 rd = (rc == non-imm) ? (rs1 arith_op non-imm) : rs1
5 rd = (rc == reg) ? (rs1 arith_op rs2) : rs1
6 rd = (rc == reg) ? (rs1 arith_op non-imm) : rs1
gcc/ChangeLog:
* ifcvt.cc (noce_emit_condzero_arith): Helper function for noce_emit_condzero_arith.
(noce_try_condzero_arith): Recognize Zicond patterns.
(noce_process_if_block): Add noce_try_condzero_arith function.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_imm_reg.c: New test.
* gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_reg_reg.c: New test.
* gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_imm_reg.c: New test.
* gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_reg_reg.c: New test.
* gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_imm_reg.c: New test.
* gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_reg_reg.c: New test.
---
gcc/ifcvt.cc | 251 ++++++++
...ionalArithmetic_compare_0_return_imm_reg.c | 553 +++++++++++++++++
...ionalArithmetic_compare_0_return_reg_reg.c | 585 ++++++++++++++++++
...nalArithmetic_compare_imm_return_imm_reg.c | 297 +++++++++
...nalArithmetic_compare_imm_return_reg_reg.c | 297 +++++++++
...nalArithmetic_compare_reg_return_imm_reg.c | 297 +++++++++
...nalArithmetic_compare_reg_return_reg_reg.c | 329 ++++++++++
7 files changed, 2609 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_imm_reg.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_reg_reg.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_imm_reg.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_reg_reg.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_imm_reg.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_reg_reg.c
diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index 0b180b4568f..0261d2f1673 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -781,12 +781,15 @@ static int noce_try_store_flag_constants (struct noce_if_info *);
static int noce_try_store_flag_mask (struct noce_if_info *);
static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx,
rtx, rtx, rtx, rtx = NULL, rtx = NULL);
+static rtx noce_emit_condzero_arith (struct noce_if_info *, rtx, enum rtx_code, rtx,
+ rtx, rtx, rtx);
static int noce_try_cmove (struct noce_if_info *);
static int noce_try_cmove_arith (struct noce_if_info *);
static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx_insn **);
static int noce_try_minmax (struct noce_if_info *);
static int noce_try_abs (struct noce_if_info *);
static int noce_try_sign_mask (struct noce_if_info *);
+static int noce_try_condzero_arith (struct noce_if_info *);
/* Return the comparison code for reversed condition for IF_INFO,
or UNKNOWN if reversing the condition is not possible. */
@@ -1830,6 +1833,60 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
return NULL_RTX;
}
+/* Helper function for noce_emit_condzero_arith. */
+
+static rtx
+noce_emit_condzero_arith (struct noce_if_info *if_info, rtx x, enum rtx_code code,
+ rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue)
+{
+ rtx cond = NULL;
+
+ /* Standard form of conditional comparison. */
+ if (GET_CODE(cmp_a) == REG && cmp_b == const0_rtx)
+ cond = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
+
+ /* Register and non-zero immediate comparison. */
+ else if (GET_CODE(cmp_a) == REG && GET_CODE(cmp_b) == CONST_INT &&
+ cmp_b != const0_rtx)
+ {
+ rtx temp1 = gen_reg_rtx (GET_MODE(cmp_a));
+ rtx temp2 = GEN_INT(-1 * INTVAL (cmp_b));
+ rtx src = gen_rtx_fmt_ee (PLUS, GET_MODE (cmp_a), cmp_a, temp2);
+ emit_insn (gen_rtx_SET (temp1, src));
+ cond = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), temp1, const0_rtx);
+ }
+
+ /* Register and Register comparison. */
+ else if (GET_CODE(cmp_a) == REG && GET_CODE(cmp_b) == REG)
+ {
+ rtx temp1 = gen_reg_rtx (GET_MODE(cmp_a));
+ rtx src = gen_rtx_fmt_ee (MINUS, GET_MODE (cmp_a), cmp_a, cmp_b);
+ emit_insn (gen_rtx_SET (temp1, src));
+ cond = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), temp1, const0_rtx);
+ }
+ else
+ return NULL_RTX;
+
+ rtx if_then_else = gen_rtx_IF_THEN_ELSE (GET_MODE (x), cond, vtrue, vfalse);
+ rtx set = gen_rtx_SET (x, if_then_else);
+
+ start_sequence ();
+ rtx_insn *insn = emit_insn (set);
+
+ if (recog_memoized (insn) >= 0)
+ {
+ rtx_insn *seq = get_insns ();
+ end_sequence ();
+ emit_insn (seq);
+
+ return x;
+ }
+
+ end_sequence ();
+
+ return NULL_RTX;
+}
+
/* Try only simple constants and registers here. More complex cases
are handled in noce_try_cmove_arith after noce_try_store_flag_arith
has had a go at it. */
@@ -2879,6 +2936,197 @@ noce_try_sign_mask (struct noce_if_info *if_info)
return TRUE;
}
+/* Convert "if (cond) x = x arith_code y; return x;" to a branchless
+ sequence using the canonical form for a conditional-zero. */
+
+static int
+noce_try_condzero_arith (struct noce_if_info *if_info)
+{
+ rtx target;
+ rtx_insn *seq;
+
+ rtx first_pattern = NULL;
+ rtx last_pattern = NULL;
+ rtx else_pattern = NULL;
+ rtx *arith, *ref_arith_op0, *ref_arith_op1;
+ rtx arith_op0, arith_op1;
+ rtx_code arith_code;
+ rtx_code cond_code = GET_CODE (if_info->cond);
+
+ machine_mode arith_mode = GET_MODE (if_info->a);
+ machine_mode cmp_mode = GET_MODE (XEXP(if_info->cond, 0));
+ if (GET_MODE_CLASS (arith_mode) != MODE_INT ||
+ GET_MODE_CLASS (cmp_mode) != MODE_INT)
+ return FALSE;
+
+ /* we shall create new pseudos. */
+ if (reload_completed)
+ return FALSE;
+
+ /* Check for cond_code. */
+ if (cond_code != EQ && cond_code != NE)
+ return FALSE;
+
+ /* Check for else_bb. */
+ if (if_info->else_bb &&
+ !(count_bb_insns(if_info->else_bb) == 1 &&
+ !JUMP_P (BB_END (if_info->then_bb)) &&
+ (else_pattern = single_set (first_active_insn (if_info->else_bb))) &&
+ GET_CODE (else_pattern) == SET &&
+ rtx_equal_p (if_info->x, XEXP(else_pattern, 0))))
+ return FALSE;
+
+ /* count_bb_insns ignores JUMP_INSN. */
+ if (JUMP_P (BB_END (if_info->then_bb)))
+ return FALSE;
+
+ if (count_bb_insns(if_info->then_bb) > 2)
+ return FALSE;
+
+ /* Optimize for sign-extension. */
+ if (count_bb_insns(if_info->then_bb) == 2)
+ {
+ last_pattern = copy_rtx (PATTERN (last_active_insn (if_info->then_bb,
+ FALSE)));
+ /* Just processing SET insn, not including other situations
+ in the single_set function. */
+ if (GET_CODE (last_pattern) != SET)
+ return FALSE;
+
+ rtx_code last_code = GET_CODE (XEXP (last_pattern, 1));
+
+ if (last_code != SIGN_EXTEND && last_code != REG)
+ return FALSE;
+ }
+
+ first_pattern = copy_rtx (PATTERN (first_active_insn (if_info->then_bb)));
+ if (GET_CODE (first_pattern) != SET)
+ return FALSE;
+
+ arith = &XEXP (first_pattern, 1);
+ arith_code = GET_CODE (*arith);
+
+ if (arith_code == SIGN_EXTEND)
+ {
+ arith = &XEXP (*arith, 0);
+ arith_code = GET_CODE (*arith);
+ }
+ /* When shift right logical a non-zero immediate to unsigned integer,
+ zero_extend and sign_extend are equal.
+ In risc-v, using zero_extend to represent shift right logical is
+ a non-canonical form, as shown in riscv.md. */
+ else if (arith_code == ZERO_EXTEND)
+ {
+ rtx *temp = arith;
+ arith = &XEXP (*arith, 0);
+ arith_code = GET_CODE (*arith);
+ if (arith_code != LSHIFTRT)
+ return FALSE;
+ /* Modify the code to sign_extend for easy subsequent recognition. */
+ PUT_CODE(*temp, SIGN_EXTEND);
+ }
+
+ if (arith_code != PLUS && arith_code != MINUS && arith_code != IOR &&
+ arith_code != XOR && arith_code != AND && arith_code != ASHIFTRT &&
+ arith_code != LSHIFTRT && arith_code != ASHIFT)
+ return FALSE;
+
+ /* Obtain the arithmetic calculation components: arith_op0 and arith_op1. */
+ arith_op0 = XEXP (*arith, 0);
+ arith_op1 = XEXP (*arith, 1);
+ ref_arith_op0 = &XEXP (*arith, 0);
+ ref_arith_op1 = &XEXP (*arith, 1);
+
+ if (GET_CODE (arith_op0) == SUBREG)
+ arith_op0 = SUBREG_REG(arith_op0);
+ if (GET_CODE (arith_op1) == SUBREG)
+ arith_op1 = SUBREG_REG(arith_op1);
+
+ /* The arithmetic calculation pattern that can only be processed
+ in insn pattern are as follows:
+ (set (reg/v:DI 137 [ rs1 ])
+ (ashiftrt:DI (reg/v:DI 137 [ rs1 ])
+ (subreg:QI (reg/v:DI 138 [ rs2 ]) 0))) */
+ if (!else_pattern && !rtx_equal_p (if_info->x, arith_op0))
+ return FALSE;
+
+ /* If else_bb is not empty. */
+ if (else_pattern && !rtx_equal_p (if_info->x, XEXP(first_pattern, 0)) &&
+ !rtx_equal_p (arith_op0, XEXP(else_pattern, 1)))
+ return FALSE;
+
+ start_sequence ();
+
+ if (arith_code == AND)
+ {
+ rtx reg1 = gen_reg_rtx (arith_mode);
+ rtx temp = gen_rtx_fmt_ee (arith_code, arith_mode, arith_op0, arith_op1);
+ emit_insn (gen_rtx_SET (reg1, temp));
+
+ rtx reg2 = gen_reg_rtx (arith_mode);
+ target = noce_emit_condzero_arith (if_info, reg2, cond_code,
+ XEXP (if_info->cond, 0),
+ XEXP (if_info->cond, 1),
+ const0_rtx, arith_op0);
+ if (!target)
+ {
+ end_sequence ();
+ return FALSE;
+ }
+ rtx ior = gen_rtx_fmt_ee (IOR, arith_mode, reg1, target);
+ emit_insn (gen_rtx_SET (if_info->x, ior));
+ }
+ else
+ {
+ /* In CONST_INT case, force arith_op1 to register. */
+ if (GET_CODE(arith_op1) == CONST_INT)
+ {
+ rtx reg = gen_reg_rtx (arith_mode);
+ emit_insn (gen_rtx_SET (reg, arith_op1));
+ arith_op1 = reg;
+ }
+
+ /* Apply for a reg as the return register for condezero. */
+ rtx reg = gen_reg_rtx (arith_mode);
+ target = noce_emit_condzero_arith (if_info, reg, cond_code,
+ XEXP (if_info->cond, 0),
+ XEXP (if_info->cond, 1),
+ arith_op1, const0_rtx);
+ if (!target)
+ {
+ end_sequence ();
+ return FALSE;
+ }
+
+ /* Update arithmetic operand in first_pattern. */
+
+ /* Shift a register. */
+ if (arith_code == ASHIFT || arith_code == ASHIFTRT ||
+ arith_code == LSHIFTRT)
+ *ref_arith_op1 = gen_rtx_SUBREG (E_QImode, target, 0);
+ else if (GET_CODE (*ref_arith_op0) == SUBREG)
+ *ref_arith_op1 = gen_rtx_SUBREG (GET_MODE (*ref_arith_op0), target, 0);
+ else
+ *ref_arith_op1 = target;
+
+ emit_insn (first_pattern);
+
+ /* Adding last_pattern to the insn chain. */
+ if (last_pattern)
+ emit_insn (last_pattern);
+ }
+
+ seq = end_ifcvt_sequence (if_info);
+
+ if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
+ return FALSE;
+
+ emit_insn_before_setloc (seq, if_info->jump,
+ INSN_LOCATION (if_info->insn_a));
+ if_info->transform_name = "noce_try_condzero_arith";
+
+ return TRUE;
+}
/* Optimize away "if (x & C) x |= C" and similar bit manipulation
transformations. */
@@ -3973,6 +4221,9 @@ noce_process_if_block (struct noce_if_info *if_info)
goto success;
if (noce_try_store_flag_mask (if_info))
goto success;
+ if (HAVE_conditional_move
+ && noce_try_condzero_arith(if_info))
+ goto success;
if (HAVE_conditional_move
&& noce_try_cmove_arith (if_info))
goto success;
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_imm_reg.c
new file mode 100644
index 00000000000..282e8a8e492
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_imm_reg.c
@@ -0,0 +1,553 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */
+
+long conditionalArithmetic_compare_0_return_imm_reg_00(long rd, long rs1,
+ long rc) {
+ if (rc == 0)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_01(long rd, long rs1,
+ long rc) {
+ if (rc != 0)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_02(long rd, long rs1,
+ long rc) {
+ if (rc)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_03(long rd, long rs1,
+ long rc) {
+ if (!rc)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_04(long rd, long rs1,
+ long rc) {
+ if (rc == 0)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_05(long rd, long rs1,
+ long rc) {
+ if (rc != 0)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_06(long rd, long rs1,
+ long rc) {
+ if (rc)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_07(long rd, long rs1,
+ long rc) {
+ if (!rc)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_08(long rd, long rs1,
+ long rc) {
+ if (rc == 0)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_09(long rd, long rs1,
+ long rc) {
+ if (rc != 0)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_10(long rd, long rs1,
+ long rc) {
+ if (rc)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_11(long rd, long rs1,
+ long rc) {
+ if (!rc)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_12(long rd, long rs1,
+ long rc) {
+ if (rc == 0)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_13(long rd, long rs1,
+ long rc) {
+ if (rc != 0)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_14(long rd, long rs1,
+ long rc) {
+ if (rc)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_15(long rd, long rs1,
+ long rc) {
+ if (!rc)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_16(long rd, long rs1,
+ long rc) {
+ if (rc == 0)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_17(long rd, long rs1,
+ long rc) {
+ if (rc != 0)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_18(long rd, long rs1,
+ long rc) {
+ if (rc)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_19(long rd, long rs1,
+ long rc) {
+ if (!rc)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_20(long rd, long rs1,
+ long rc) {
+ if (rc == 0)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_21(long rd, long rs1,
+ long rc) {
+ if (rc != 0)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_22(long rd, long rs1,
+ long rc) {
+ if (rc)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_23(long rd, long rs1,
+ long rc) {
+ if (!rc)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_24(long rd, long rs1,
+ long rc) {
+ if (rc == 0)
+ rd = ((unsigned long)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_25(long rd, long rs1,
+ long rc) {
+ if (rc != 0)
+ rd = ((unsigned long)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_26(long rd, long rs1,
+ long rc) {
+ if (rc)
+ rd = ((unsigned long)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_27(long rd, long rs1,
+ long rc) {
+ if (!rc)
+ rd = ((unsigned long)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_28(long rd, long rs1,
+ long rc) {
+ if (rc == 0)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_29(long rd, long rs1,
+ long rc) {
+ if (rc != 0)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_30(long rd, long rs1,
+ long rc) {
+ if (rc)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_imm_reg_31(long rd, long rs1,
+ long rc) {
+ if (!rc)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_32(int rd, int rs1, int rc) {
+ if (rc == 0)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_33(int rd, int rs1, int rc) {
+ if (rc != 0)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_34(int rd, int rs1, int rc) {
+ if (rc)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_35(int rd, int rs1, int rc) {
+ if (!rc)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_36(int rd, int rs1, int rc) {
+ if (rc == 0)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_37(int rd, int rs1, int rc) {
+ if (rc != 0)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_38(int rd, int rs1, int rc) {
+ if (rc)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_39(int rd, int rs1, int rc) {
+ if (!rc)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_40(int rd, int rs1, int rc) {
+ if (rc == 0)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_41(int rd, int rs1, int rc) {
+ if (rc != 0)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_42(int rd, int rs1, int rc) {
+ if (rc)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_43(int rd, int rs1, int rc) {
+ if (!rc)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_44(int rd, int rs1, int rc) {
+ if (rc == 0)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_45(int rd, int rs1, int rc) {
+ if (rc != 0)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_46(int rd, int rs1, int rc) {
+ if (rc)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_47(int rd, int rs1, int rc) {
+ if (!rc)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_48(int rd, int rs1, int rc) {
+ if (rc == 0)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_49(int rd, int rs1, int rc) {
+ if (rc != 0)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_50(int rd, int rs1, int rc) {
+ if (rc)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_51(int rd, int rs1, int rc) {
+ if (!rc)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_52(int rd, int rs1, int rc) {
+ if (rc == 0)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_53(int rd, int rs1, int rc) {
+ if (rc != 0)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_54(int rd, int rs1, int rc) {
+ if (rc)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_55(int rd, int rs1, int rc) {
+ if (!rc)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_56(int rd, int rs1, int rc) {
+ if (rc == 0)
+ rd = ((unsigned int)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_57(int rd, int rs1, int rc) {
+ if (rc != 0)
+ rd = ((unsigned int)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_58(int rd, int rs1, int rc) {
+ if (rc)
+ rd = ((unsigned int)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_59(int rd, int rs1, int rc) {
+ if (!rc)
+ rd = ((unsigned int)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_60(int rd, int rs1, int rc) {
+ if (rc == 0)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_61(int rd, int rs1, int rc) {
+ if (rc != 0)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_62(int rd, int rs1, int rc) {
+ if (rc)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_imm_reg_63(int rd, int rs1, int rc) {
+ if (!rc)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 32 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 32 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_reg_reg.c
new file mode 100644
index 00000000000..15efcf538e5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_0_return_reg_reg.c
@@ -0,0 +1,585 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */
+
+long conditionalArithmetic_compare_0_return_reg_reg_00(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 0)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_01(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 0)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_02(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_03(long rd, long rs1,
+ long rs2, long rc) {
+ if (!rc)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_04(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 0)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_05(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 0)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_06(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_07(long rd, long rs1,
+ long rs2, long rc) {
+ if (!rc)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_08(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 0)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_09(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 0)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_10(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_11(long rd, long rs1,
+ long rs2, long rc) {
+ if (!rc)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_12(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 0)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_13(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 0)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_14(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_15(long rd, long rs1,
+ long rs2, long rc) {
+ if (!rc)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_16(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 0)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_17(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 0)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_18(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_19(long rd, long rs1,
+ long rs2, long rc) {
+ if (!rc)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_20(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 0)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_21(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 0)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_22(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_23(long rd, long rs1,
+ long rs2, long rc) {
+ if (!rc)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_24(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 0)
+ rd = ((unsigned long)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_25(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 0)
+ rd = ((unsigned long)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_26(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc)
+ rd = ((unsigned long)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_27(long rd, long rs1,
+ long rs2, long rc) {
+ if (!rc)
+ rd = ((unsigned long)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_28(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 0)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_29(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 0)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_30(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_0_return_reg_reg_31(long rd, long rs1,
+ long rs2, long rc) {
+ if (!rc)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_32(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc == 0)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_33(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc != 0)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_34(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_35(int rd, int rs1, int rs2,
+ int rc) {
+ if (!rc)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_36(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc == 0)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_37(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc != 0)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_38(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_39(int rd, int rs1, int rs2,
+ int rc) {
+ if (!rc)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_40(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc == 0)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_41(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc != 0)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_42(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_43(int rd, int rs1, int rs2,
+ int rc) {
+ if (!rc)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_44(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc == 0)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_45(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc != 0)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_46(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_47(int rd, int rs1, int rs2,
+ int rc) {
+ if (!rc)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_48(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc == 0)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_49(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc != 0)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_50(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_51(int rd, int rs1, int rs2,
+ int rc) {
+ if (!rc)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_52(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc == 0)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_53(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc != 0)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_54(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_55(int rd, int rs1, int rs2,
+ int rc) {
+ if (!rc)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_56(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc == 0)
+ rd = ((unsigned int)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_57(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc != 0)
+ rd = ((unsigned int)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_58(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc)
+ rd = ((unsigned int)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_59(int rd, int rs1, int rs2,
+ int rc) {
+ if (!rc)
+ rd = ((unsigned int)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_60(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc == 0)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_61(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc != 0)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_62(int rd, int rs1, int rs2,
+ int rc) {
+ if (rc)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_0_return_reg_reg_63(int rd, int rs1, int rs2,
+ int rc) {
+ if (!rc)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 32 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 32 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_imm_reg.c
new file mode 100644
index 00000000000..6647640acf8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_imm_reg.c
@@ -0,0 +1,297 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */
+
+long conditionalArithmetic_compare_imm_return_imm_reg_00(long rd, long rs1,
+ long rc) {
+ if (rc == 10)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_01(long rd, long rs1,
+ long rc) {
+ if (rc != 10)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_02(long rd, long rs1,
+ long rc) {
+ if (rc == 10)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_03(long rd, long rs1,
+ long rc) {
+ if (rc != 10)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_04(long rd, long rs1,
+ long rc) {
+ if (rc == 10)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_05(long rd, long rs1,
+ long rc) {
+ if (rc != 10)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_06(long rd, long rs1,
+ long rc) {
+ if (rc == 10)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_07(long rd, long rs1,
+ long rc) {
+ if (rc != 10)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_08(long rd, long rs1,
+ long rc) {
+ if (rc == 10)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_09(long rd, long rs1,
+ long rc) {
+ if (rc != 10)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_10(long rd, long rs1,
+ long rc) {
+ if (rc == 10)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_11(long rd, long rs1,
+ long rc) {
+ if (rc != 10)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_12(long rd, long rs1,
+ long rc) {
+ if (rc == 10)
+ rd = ((unsigned long)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_13(long rd, long rs1,
+ long rc) {
+ if (rc != 10)
+ rd = ((unsigned long)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_14(long rd, long rs1,
+ long rc) {
+ if (rc == 10)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_imm_reg_15(long rd, long rs1,
+ long rc) {
+ if (rc != 10)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_16(int rd, int rs1,
+ int rc) {
+ if (rc == 10)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_17(int rd, int rs1,
+ int rc) {
+ if (rc != 10)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_18(int rd, int rs1,
+ int rc) {
+ if (rc == 10)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_19(int rd, int rs1,
+ int rc) {
+ if (rc != 10)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_20(int rd, int rs1,
+ int rc) {
+ if (rc == 10)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_21(int rd, int rs1,
+ int rc) {
+ if (rc != 10)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_22(int rd, int rs1,
+ int rc) {
+ if (rc == 10)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_23(int rd, int rs1,
+ int rc) {
+ if (rc != 10)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_24(int rd, int rs1,
+ int rc) {
+ if (rc == 10)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_25(int rd, int rs1,
+ int rc) {
+ if (rc != 10)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_26(int rd, int rs1,
+ int rc) {
+ if (rc == 10)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_27(int rd, int rs1,
+ int rc) {
+ if (rc != 10)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_28(int rd, int rs1,
+ int rc) {
+ if (rc == 10)
+ rd = ((unsigned int)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_29(int rd, int rs1,
+ int rc) {
+ if (rc != 10)
+ rd = ((unsigned int)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_30(int rd, int rs1,
+ int rc) {
+ if (rc == 10)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_imm_reg_31(int rd, int rs1,
+ int rc) {
+ if (rc != 10)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 16 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 16 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_reg_reg.c
new file mode 100644
index 00000000000..859639c1676
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_imm_return_reg_reg.c
@@ -0,0 +1,297 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */
+
+long conditionalArithmetic_compare_imm_return_reg_reg_00(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 10)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_01(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 10)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_02(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 10)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_03(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 10)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_04(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 10)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_05(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 10)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_06(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 10)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_07(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 10)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_08(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 10)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_09(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 10)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_10(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 10)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_11(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 10)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_12(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 10)
+ rd = ((unsigned long)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_13(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 10)
+ rd = ((unsigned long)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_14(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc == 10)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_imm_return_reg_reg_15(long rd, long rs1,
+ long rs2, long rc) {
+ if (rc != 10)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_16(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc == 10)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_17(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc != 10)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_18(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc == 10)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_19(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc != 10)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_20(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc == 10)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_21(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc != 10)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_22(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc == 10)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_23(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc != 10)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_24(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc == 10)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_25(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc != 10)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_26(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc == 10)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_27(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc != 10)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_28(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc == 10)
+ rd = ((unsigned int)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_29(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc != 10)
+ rd = ((unsigned int)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_30(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc == 10)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_imm_return_reg_reg_31(int rd, int rs1,
+ int rs2, int rc) {
+ if (rc != 10)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 16 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 16 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_imm_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_imm_reg.c
new file mode 100644
index 00000000000..7affe1d9baa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_imm_reg.c
@@ -0,0 +1,297 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */
+
+long conditionalArithmetic_compare_reg_return_imm_reg_00(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_01(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_02(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_03(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_04(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_05(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_06(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_07(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_08(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_09(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_10(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_11(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_12(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 == rc2)
+ rd = ((unsigned long)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_13(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 != rc2)
+ rd = ((unsigned long)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_14(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_imm_reg_15(long rd, long rs1,
+ long rc1, long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_16(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_17(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 + 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_18(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_19(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 - 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_20(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_21(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 | 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_22(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_23(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 ^ 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_24(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_25(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 << 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_26(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_27(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_28(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 == rc2)
+ rd = ((unsigned int)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_29(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 != rc2)
+ rd = ((unsigned int)rs1) >> 2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_30(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_imm_reg_31(int rd, int rs1,
+ int rc1, int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 & 20;
+ else
+ rd = rs1;
+ return rd;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 16 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 16 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_reg_reg.c
new file mode 100644
index 00000000000..8b0959e534b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-conditionalArithmetic_compare_reg_return_reg_reg.c
@@ -0,0 +1,329 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os"} } */
+
+long conditionalArithmetic_compare_reg_return_reg_reg_00(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_01(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_02(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_03(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_04(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_05(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_06(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_07(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_08(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_09(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_10(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_11(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_12(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 == rc2)
+ rd = ((unsigned long)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_13(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 != rc2)
+ rd = ((unsigned long)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_14(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 == rc2)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+long conditionalArithmetic_compare_reg_return_reg_reg_15(long rd, long rs1,
+ long rs2, long rc1,
+ long rc2) {
+ if (rc1 != rc2)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_16(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_17(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 + rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_18(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_19(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 - rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_20(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_21(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 | rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_22(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_23(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 ^ rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_24(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_25(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 << rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_26(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_27(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_28(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 == rc2)
+ rd = ((unsigned int)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_29(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 != rc2)
+ rd = ((unsigned int)rs1) >> rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_30(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 == rc2)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+int conditionalArithmetic_compare_reg_return_reg_reg_31(int rd, int rs1,
+ int rs2, int rc1,
+ int rc2) {
+ if (rc1 != rc2)
+ rd = rs1 & rs2;
+ else
+ rd = rs1;
+ return rd;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 16 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 16 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
--
2.17.1
^ permalink raw reply [flat|nested] 32+ messages in thread