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 mov<mode>cc

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.

Jeff
commit 9e3fd332959930efd3cabf222afbac910507d2f3
Author: Xiao Zeng <zengx...@eswincomputing.com>
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 (mov<mode>cc): Allow TARGET_ZICOND.  Use
            sfb_alu_operand for both arms of the conditional move.
    
            Co-authored-by: Jeff Law <j...@ventanamicro.com>

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 (&code, &op0, &op1, 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 (&code, &op0, &op1, 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 (&code, &op0, &op1, 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, mode));
+         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;
+       }
+      /* reg, 0 or imm, 0  */
+      else if ((REG_P (cons)
+               || (CONST_INT_P (cons) && cons != CONST0_RTX (mode)))
+              && alt == CONST0_RTX (mode))
+       {
+         riscv_emit_int_compare (&code, &op0, &op1, true);
+         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;
+       }
+    }
 
   return false;
 }
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 24819cc737c..688fd697255 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2492,9 +2492,9 @@ (define_insn "*branch<mode>"
 (define_expand "mov<mode>cc"
   [(set (match_operand:GPR 0 "register_operand")
        (if_then_else:GPR (match_operand 1 "comparison_operator")
-                         (match_operand:GPR 2 "reg_or_0_operand")
+                         (match_operand:GPR 2 "sfb_alu_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]))

Reply via email to