Re: [PATCH v3] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to 0

2023-09-26 Thread Jeff Law




On 8/1/23 19:38, Xiao Zeng wrote:

This patch recognizes Zicond patterns when the select pattern
with condition eq or neq to 0 (using eq 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_expand_conditional_move): Recognize
 Zicond patterns
 * config/riscv/riscv.md: Recognize Zicond patterns through movcc

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.
I've added -Oz and -Og to the skip list and pushed the tests up to the 
trunk.


jeff


Re: Re: [PATCH v3] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to 0

2023-08-05 Thread Xiao Zeng
On Sat, Aug 05, 2023 at 05:31:00 AM  Jeff Law  wrote:
>
>On 8/1/23 19:38, Xiao Zeng wrote:
>> This patch recognizes Zicond patterns when the select pattern
>> with condition eq or neq to 0 (using eq 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_expand_conditional_move): Recognize
>>  Zicond patterns
>>  * config/riscv/riscv.md: Recognize Zicond patterns through 
>>movcc
>So I've made minor adjustments to the remaining three cases.  First we
>need to check the code before optimizing the cases were one of the arms
>of the conditional move matches op0.
>
>I slightly adjusted the case for out of range constants.  Its better to
>check SMALL_OPERAND rather than testing for specific constants.  And
>when that triggers, we can just force the value into a register and
>continue as-is rather than recursing.
> 
These changes make the code more concise and readable. Thumbs up!

>The patch I'm committing fixes one comment typo (whitespace) and a bit
>of accidentally duplicated code I added in a prior commit.
>
>Next up Raphael's patches to handle nontrival conditionals by emiting an
>scc insn :-) 
It would be great to see other implementations for conditional execution. :-)

>
>Jeff
>
>ps.  I'm deferrring the testsuite bits until we sort out the costing
>problems.  THey're definitely not forgotten and I still use them in my
>local tree. 
Thank you Jeff, I look forward to a unified, complete and concise
implementation method for cost calculation as soon as possible.
 
Thanks
Xiao Zeng



Re: [PATCH v3] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to 0

2023-08-04 Thread Jeff Law via Gcc-patches



On 8/1/23 19:38, Xiao Zeng wrote:

This patch recognizes Zicond patterns when the select pattern
with condition eq or neq to 0 (using eq 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_expand_conditional_move): Recognize
 Zicond patterns
 * config/riscv/riscv.md: Recognize Zicond patterns through movcc
So I've made minor adjustments to the remaining three cases.  First we 
need to check the code before optimizing the cases were one of the arms 
of the conditional move matches op0.


I slightly adjusted the case for out of range constants.  Its better to 
check SMALL_OPERAND rather than testing for specific constants.  And 
when that triggers, we can just force the value into a register and 
continue as-is rather than recursing.


The patch I'm committing fixes one comment typo (whitespace) and a bit 
of accidentally duplicated code I added in a prior commit.


Next up Raphael's patches to handle nontrival conditionals by emiting an 
scc insn :-)


Jeff

ps.  I'm deferrring the testsuite bits until we sort out the costing 
problems.  THey're definitely not forgotten and I still use them in my 
local tree.
commit 4e87c953d16377457b31b65b6c3268d932e462ab
Author: Xiao Zeng 
Date:   Fri Aug 4 17:23:56 2023 -0400

[PATCH v3] [RISC-V] Generate Zicond instruction for select pattern with 
condition eq or neq to 0

This patch recognizes Zicond patterns when the select pattern
with condition eq or neq to 0 (using eq 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_expand_conditional_move): Recognize
more Zicond patterns.  Fix whitespace typo.
(riscv_rtx_costs): Remove accidental code duplication.

Co-authored-by: Jeff Law 

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 8b725610815..7728cd34569 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2522,20 +2522,6 @@ 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_MODE (XEXP (x, 1
-  || (GET_CODE (XEXP (x, 2)) == REG
-  && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 2
-  || (GET_CODE (XEXP (x, 1)) == REG
-  && rtx_equal_p (XEXP (x, 1), XEXP (XEXP (x, 0), 0)))
-  || (GET_CODE (XEXP (x, 1)) == REG
-  && rtx_equal_p (XEXP (x, 2), XEXP (XEXP (x, 0), 0)
-   {
- *total = COSTS_N_INSNS (1);
- return true;
-   }
   else if (LABEL_REF_P (XEXP (x, 1)) && XEXP (x, 2) == pc_rtx)
{
  if (equality_operator (XEXP (x, 0), mode)
@@ -3583,7 +3569,7 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx 
cons, rtx alt)
   /* The expander is a bit loose in its specification of the true
 arm of the conditional move.  That allows us to support more
 cases for extensions which are more general than SFB.  But
-   does mean we need to force CONS into a register at this point.  */
+does mean we need to force CONS into a register at this point.  */
   cons = force_reg (GET_MODE (dest), cons);
   emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
  cond, cons, alt)));
@@ -3628,6 +3614,40 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx 
cons, rtx alt)
  riscv_emit_binary (PLUS, dest, dest, cons);
  return true;
}
+  /* imm, reg  */
+  else if (CONST_INT_P (cons) && cons != CONST0_RTX (mode) && REG_P (alt))
+   {
+ /* Optimize for register value of 0.  */
+ if (code == NE && rtx_equal_p (op0, alt) && op1 == CONST0_RTX (mode))
+   {
+ 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 (, , , true);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+
+ rtx temp1 = gen_reg_rtx (mode);
+ rtx temp2 = gen_int_mode (-1 * INTVAL (cons), mode);
+
+ /* TEMP2 might not fit into a signed 12 bit immediate suitable
+for an addi 

Re: [PATCH v3] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to 0

2023-08-03 Thread Jeff Law via Gcc-patches



On 8/1/23 19:38, Xiao Zeng wrote:

This patch recognizes Zicond patterns when the select pattern
with condition eq or neq to 0 (using eq 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_expand_conditional_move): Recognize
 Zicond patterns
 * config/riscv/riscv.md: Recognize Zicond patterns through movcc

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.
So I've done a partial commit of this patch.  I'm still evaluating a few 
of the cases and haven't included them yet.


The most notable change I've made is the 0, imm case and imm, 0 case can 
trivially handle 0, reg and reg, 0 as well.  I also changed the imm, imm 
case to use gen_int_mode rather than GEN_INT.  It may not be strictly 
necessary here, but it does future proof the code a bit if we were to 
support additional mode (and we may well want to do that).


I'm hoping to get the rest of patch #3 in today, though I suspect the 
testing will push it into tomorrow.  Then I want to layer on Raphael's 
code to handle missed cases using scc insns.


Jeffcommit 9e3fd332959930efd3cabf222afbac910507d2f3
Author: Xiao Zeng 
Date:   Thu Aug 3 16:09:46 2023 -0400

[PATCH 3/5] [RISC-V] Generate Zicond instruction for select pattern with 
condition eq or neq to 0

[ This is a partial commit.  So not all the cases mentioned by
  Xiao are currently handled. ]

This patch recognizes Zicond patterns when the select pattern
with condition eq or neq to 0 (using eq 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_expand_conditional_move): Recognize
various Zicond patterns.
* config/riscv/riscv.md (movcc): Allow TARGET_ZICOND.  Use
sfb_alu_operand for both arms of the conditional move.

Co-authored-by: Jeff Law 

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index d8fab68dbb4..8b725610815 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3580,15 +3580,67 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx 
cons, rtx alt)
   riscv_emit_int_compare (, , , need_eq_ne_p);
   rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
 
-  /* The expander allows (const_int 0) for CONS for the benefit of
-TARGET_XTHEADCONDMOV, but that case isn't supported for
-TARGET_SFB_ALU.  So force that operand into a register if
-necessary.  */
+  /* The expander is a bit loose in its specification of the true
+arm of the conditional move.  That allows us to support more
+cases for extensions which are more general than SFB.  But
+   does mean we need to force CONS into a register at this point.  */
   cons = force_reg (GET_MODE (dest), cons);
   emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
  cond, cons, alt)));
   return true;
 }
+  else if (TARGET_ZICOND
+  && (code == EQ || code == NE)
+  && GET_MODE_CLASS (mode) == MODE_INT)
+{
+  /* The comparison must be comparing WORD_MODE objects.   We must
+enforce that so that we don't strip away a sign_extension
+thinking it is unnecessary.  We might consider using
+riscv_extend_operands if they are not already properly extended.  */
+  if (GET_MODE (op0) != word_mode || GET_MODE (op1) != word_mode)
+   return false;
+
+  /* 0, reg or 0, imm */
+  if (cons == CONST0_RTX (mode)
+ && (REG_P (alt)
+ || (CONST_INT_P (alt) && alt != CONST0_RTX (mode
+   {
+ riscv_emit_int_compare (, , , true);
+ 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 (CONST_INT_P (cons) && cons != CONST0_RTX (mode)
+  && CONST_INT_P (alt) && alt != CONST0_RTX (mode))
+   {
+ riscv_emit_int_compare (, , , true);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ HOST_WIDE_INT t = INTVAL (alt) - INTVAL (cons);
+ alt = force_reg (mode, gen_int_mode (t, 

[PATCH v3] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to 0

2023-08-01 Thread Xiao Zeng
This patch recognizes Zicond patterns when the select pattern
with condition eq or neq to 0 (using eq 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_expand_conditional_move): Recognize
Zicond patterns
* config/riscv/riscv.md: Recognize Zicond patterns through movcc

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 | 137 ++
 gcc/config/riscv/riscv.md |   4 +-
 .../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, 407 insertions(+), 2 deletions(-)
 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 b6a57d0306d..6353d08ba9d 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3557,6 +3557,143 @@ 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)
+{
+  /* 0 + imm  */
+  if (CONST_INT_P (cons) && cons == CONST0_RTX (GET_MODE (cons))
+  && CONST_INT_P (alt) && alt != CONST0_RTX (GET_MODE (alt)))
+{
+  riscv_emit_int_compare (, , , true);
+  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 (CONST_INT_P (cons) && cons != CONST0_RTX (GET_MODE (cons))
+   && CONST_INT_P (alt) && alt != CONST0_RTX (GET_MODE (alt)))
+{
+  riscv_emit_int_compare (, , , true);
+  rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+  alt = force_reg (mode, GEN_INT (INTVAL (alt) - INTVAL (cons)));
+  emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cond,
+  CONST0_RTX 
(mode),
+  alt)));
+  riscv_emit_binary (PLUS, dest, dest, cons);
+  return true;
+}
+  /* imm + reg  */
+  else if (CONST_INT_P (cons) && cons != CONST0_RTX (GET_MODE (cons))
+   && REG_P (alt))
+{
+  if (op0 == alt && op1 == CONST0_RTX (GET_MODE (op1)))
+{
+  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;
+}
+  /* Handle the special situation of: -2048 == INTVAL (alt)
+ to avoid failure due to an unrecognized insn. Let the costing
+ model determine if the conditional move sequence is better
+ than the branching sequence.  */
+  if (-2048 == INTVAL (cons))
+{
+  rtx reg = gen_reg_rtx (mode);
+  emit_insn (gen_rtx_SET (reg, cons));
+  return riscv_expand_conditional_move (dest, op, reg, alt);
+}
+  riscv_emit_int_compare (, , , true);
+  rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+  rtx temp = GEN_INT (-1 * INTVAL (cons));
+  riscv_emit_binary (PLUS, alt, alt, temp);
+  emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cond,
+  CONST0_RTX 
(mode),
+  alt)));
+  riscv_emit_binary (PLUS, dest, dest, cons);
+  return true;
+}
+  /* imm + 0  */
+  else if (CONST_INT_P (cons) && cons !=