]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH 3/5] [RISC-V] Generate Zicond instruction for select pattern with condition...
authorXiao Zeng <zengxiao@eswincomputing.com>
Thu, 3 Aug 2023 20:09:46 +0000 (16:09 -0400)
committerJeff Law <jeffreyalaw@gmail.com>
Thu, 3 Aug 2023 20:14:02 +0000 (16:14 -0400)
[ 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 <jlaw@ventanamicro.com>
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.md

index d8fab68dbb4a8563307f66dad66f087fe00b287f..8b7256108157aa12234cc9a04ec95b99b1a3c410 100644 (file)
@@ -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;
 }
index 24819cc737cd2cc9643e98b84950e94873ae7f38..688fd697255b94dc6a148f0430b36b6039077c4c 100644 (file)
 (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]))