[PATCH] RISC-V: Remove the redundant expressions in the and3.

2023-07-13 Thread Die Li
When generating the gen_and3 function based on the and3
template, it produces the expression emit_insn (gen_rtx_SET (operand0,
gen_rtx_AND (, operand1, operand2)));, which is identical to the
portion I removed in this patch. Therefore, the redundant portion can be
deleted.

Signed-off-by: Die Li 

gcc/ChangeLog:

* config/riscv/riscv.md: Remove redundant portion in and3.
---
 gcc/config/riscv/riscv.md | 5 -
 1 file changed, 5 deletions(-)

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 7988026d129..c4f8eb9488e 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -1491,11 +1491,6 @@
  DONE;
}
 }
-  else
-{
-  emit_move_insn (operands[0], gen_rtx_AND (mode, operands[1], 
operands[2]));
-  DONE;
-}
 })
 
 (define_insn "*and3"
-- 
2.17.1



[PATCH] RISC-V: Remove unnecessary md pattern for TARGET_XTHEADCONDMOV

2023-06-01 Thread Die Li
There are 2 small changes in this patch, but they do not affect the result.

1. Remove unnecessary md pattern for TARGET_XTHEADCONDMOV in thead.md. The 
operands[4]
in "if_then_else" are always comparison operations, so the generated rtl does 
not match
the pattern that is expected to be deleted.

2. Change operands[4] from const0_rtx to operands[1] to maintain rtl 
consistency. Although
when output assembly, only operands[4] CODE will affect the output result.

Signed-off-by: Die Li 

gcc/ChangeLog:

* config/riscv/thead.md (*th_cond_gpr_mov): Delete.
---
 gcc/config/riscv/thead.md | 15 +--
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 0623607d3dc..ea377872bde 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -120,25 +120,12 @@
   /* Invert the condition and take else-block.  */
   rtx_code code = GET_CODE (operands[4]);
   code = (code == EQ) ? NE : EQ;
-  operands[4] = gen_rtx_fmt_ee (code, VOIDmode, const0_rtx, const0_rtx);
+  operands[4] = gen_rtx_fmt_ee (code, VOIDmode, operands[1], const0_rtx);
   return "th.mv%C4z\t%0,%z3,%1";
 }
   [(set_attr "type" "condmove")
(set_attr "mode" "")])
 
-(define_insn "*th_cond_gpr_mov"
-  [(set (match_operand:GPR 0 "register_operand" "=r,r")
-   (if_then_else:GPR
-(match_operand:GPR2 1 "register_operand" "r,r")
-(match_operand:GPR 2 "reg_or_0_operand" "rJ,0")
-(match_operand:GPR 3 "reg_or_0_operand" "0,rJ")))]
-  "TARGET_XTHEADCONDMOV"
-  "@
-   th.mvnez\t%0,%z2,%1
-   th.mveqz\t%0,%z3,%1"
-  [(set_attr "type" "condmove")
-   (set_attr "mode" "")])
-
 ;; XTheadFmv
 
 ;; In RV32, we lack fmv.x.d and fmv.d.x, but XTheadFmv has instructions
-- 
2.17.1



[PATCH] RISC-V: Optimize TARGET_XTHEADCONDMOV

2023-05-25 Thread Die Li
This patch allows less instructions to be used when TARGET_XTHEADCONDMOV is 
enabled.

Provide an example from the existing testcases.

Testcase:
int ConEmv_imm_imm_reg(int x, int y){
  if (x == 1000) return 10;
  return y;
}

Cflags:
-O2 -march=rv64gc_xtheadcondmov -mabi=lp64d

before patch:
ConEmv_imm_imm_reg:
addia5,a0,-1000
li  a0,10
th.mvneza0,zero,a5
th.mveqza1,zero,a5
or  a0,a0,a1
ret

after patch:
ConEmv_imm_imm_reg:
addia5,a0,-1000
li  a0,10
th.mvneza0,a1,a5
ret

Signed-off-by: Die Li 

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_expand_conditional_move_onesided): 
Delete.
(riscv_expand_conditional_move):  Reuse the TARGET_SFB_ALU expand 
process for TARGET_XTHEADCONDMOV

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-indirect-rv32.c: Update the output.
* gcc.target/riscv/xtheadcondmov-indirect-rv64.c: Likewise.
---
 gcc/config/riscv/riscv.cc | 44 +++--
 .../riscv/xtheadcondmov-indirect-rv32.c   | 48 +++
 .../riscv/xtheadcondmov-indirect-rv64.c   | 48 +++
 3 files changed, 42 insertions(+), 98 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 09fc9e5d95e..8b8ac9181ba 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3442,37 +3442,6 @@ riscv_expand_conditional_branch (rtx label, rtx_code 
code, rtx op0, rtx op1)
   emit_jump_insn (gen_condjump (condition, label));
 }
 
-/* Helper to emit two one-sided conditional moves for the movecc.  */
-
-static void
-riscv_expand_conditional_move_onesided (rtx dest, rtx cons, rtx alt,
-   rtx_code code, rtx op0, rtx op1)
-{
-  machine_mode mode = GET_MODE (dest);
-
-  gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
-  gcc_assert (reg_or_0_operand (cons, mode));
-  gcc_assert (reg_or_0_operand (alt, mode));
-
-  riscv_emit_int_compare (, , , true);
-  rtx cond = gen_rtx_fmt_ee (code, mode, op0, op1);
-
-  rtx tmp1 = gen_reg_rtx (mode);
-  rtx tmp2 = gen_reg_rtx (mode);
-
-  emit_insn (gen_rtx_SET (tmp1, gen_rtx_IF_THEN_ELSE (mode, cond,
- cons, const0_rtx)));
-
-  /* We need to expand a sequence for both blocks and we do that such,
- that the second conditional move will use the inverted condition.
- We use temporaries that are or'd to the dest register.  */
-  cond = gen_rtx_fmt_ee ((code == EQ) ? NE : EQ, mode, op0, op1);
-  emit_insn (gen_rtx_SET (tmp2, gen_rtx_IF_THEN_ELSE (mode, cond,
- alt, const0_rtx)));
-
-  emit_insn (gen_rtx_SET (dest, gen_rtx_IOR (mode, tmp1, tmp2)));
- }
-
 /* Emit a cond move: If OP holds, move CONS to DEST; else move ALT to DEST.
Return 0 if expansion failed.  */
 
@@ -3483,6 +3452,7 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx 
cons, rtx alt)
   rtx_code code = GET_CODE (op);
   rtx op0 = XEXP (op, 0);
   rtx op1 = XEXP (op, 1);
+  bool need_eq_ne_p = false;
 
   if (TARGET_XTHEADCONDMOV
   && GET_MODE_CLASS (mode) == MODE_INT
@@ -3492,14 +3462,12 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx 
cons, rtx alt)
   && GET_MODE (op0) == mode
   && GET_MODE (op1) == mode
   && (code == EQ || code == NE))
+need_eq_ne_p = true;
+
+  if (need_eq_ne_p || (TARGET_SFB_ALU
+  && GET_MODE (op0) == word_mode))
 {
-  riscv_expand_conditional_move_onesided (dest, cons, alt, code, op0, op1);
-  return true;
-}
-  else if (TARGET_SFB_ALU
-  && GET_MODE (op0) == word_mode)
-{
-  riscv_emit_int_compare (, , );
+  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
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c
index 9afdc2eabfd..e2b135f3d00 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c
@@ -1,15 +1,13 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -march=rv32gc_xtheadcondmov -mabi=ilp32 
-mriscv-attribute" } */
-/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os" "-Og" "-O3" "-Oz" "-flto"} } */
 /* { dg-final { check-function-bodies "**" ""  } } */
 
 /*
 **ConEmv_imm_imm_reg:
 ** addia5,a0,-1000
 ** li  a0,10
-** th.mvneza0,zero,a5
-** th.mveqza1,zero,a5
-** or  a0,a0,a1
+** th.mvneza0,a1,a5

[PATCH] [RISC-V] Fix riscv_expand_conditional_move.

2023-04-27 Thread Die Li
Two issues have been observed in current riscv_expand_conditional_move
implementation.
1. Before introduction of TARGET_XTHEADCONDMOV, op0 of comparision expression
is used for mode comparision with word_mode, but after TARGET_XTHEADCONDMOV
megered with TARGET_SFB_ALU, dest of if-then-else is used for mode comparision 
with
word_mode, and from md file mode of dest is DI or SI which can be different with
word_mode in RV64.

2. TARGET_XTHEADCONDMOV cannot be generated when the mode of the comparison is 
E_VOID.

This patch solves the issues above.

Provide an example from the newly added test case.

Testcase:
int ConNmv_reg_reg_reg(int x, int y, int z, int n){
  if (x != y) return z;
  return n;
}

Cflags:
-O2 -march=rv64gc_xtheadcondmov -mabi=lp64d

before patch:
ConNmv_reg_reg_reg:
bne a0,a1,.L23
mv  a2,a3
.L23:
mv  a0,a2
ret

after patch:
ConNmv_reg_reg_reg:
sub a1,a0,a1
th.mveqza2,zero,a1
th.mvneza3,zero,a1
or  a0,a2,a3
ret

Co-Authored by: Fei Gao 
Signed-off-by: Die Li 

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_expand_conditional_move): Fix mode 
checking.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-indirect-rv32.c: New test.
* gcc.target/riscv/xtheadcondmov-indirect-rv64.c: New test.
---
 gcc/config/riscv/riscv.cc |   4 +-
 .../riscv/xtheadcondmov-indirect-rv32.c   | 116 ++
 .../riscv/xtheadcondmov-indirect-rv64.c   | 116 ++
 3 files changed, 234 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv64.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 1529855a2b4..30ace45dc5f 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3411,7 +3411,7 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx 
cons, rtx alt)
   && GET_MODE_CLASS (mode) == MODE_INT
   && reg_or_0_operand (cons, mode)
   && reg_or_0_operand (alt, mode)
-  && GET_MODE (op) == mode
+  && (GET_MODE (op) == mode || GET_MODE (op) == E_VOIDmode)
   && GET_MODE (op0) == mode
   && GET_MODE (op1) == mode
   && (code == EQ || code == NE))
@@ -3420,7 +3420,7 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx 
cons, rtx alt)
   return true;
 }
   else if (TARGET_SFB_ALU
-  && mode == word_mode)
+  && GET_MODE (op0) == word_mode)
 {
   riscv_emit_int_compare (, , );
   rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c
new file mode 100644
index 000..9afdc2eabfd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-indirect-rv32.c
@@ -0,0 +1,116 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv32gc_xtheadcondmov -mabi=ilp32 
-mriscv-attribute" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+/* { dg-final { check-function-bodies "**" ""  } } */
+
+/*
+**ConEmv_imm_imm_reg:
+** addia5,a0,-1000
+** li  a0,10
+** th.mvneza0,zero,a5
+** th.mveqza1,zero,a5
+** or  a0,a0,a1
+** ret
+*/
+int ConEmv_imm_imm_reg(int x, int y){
+  if (x == 1000) return 10;
+  return y;
+}
+
+/*
+**ConEmv_imm_reg_reg:
+** addia5,a0,-1000
+** th.mvneza1,zero,a5
+** th.mveqza2,zero,a5
+** or  a0,a1,a2
+** ret
+*/
+int ConEmv_imm_reg_reg(int x, int y, int z){
+  if (x == 1000) return y;
+  return z;
+}
+
+/*
+**ConEmv_reg_imm_reg:
+** sub a1,a0,a1
+** li  a0,10
+** th.mvneza0,zero,a1
+** th.mveqza2,zero,a1
+** or  a0,a0,a2
+** ret
+*/
+int ConEmv_reg_imm_reg(int x, int y, int z){
+  if (x == y) return 10;
+  return z;
+}
+
+/*
+**ConEmv_reg_reg_reg:
+** sub a1,a0,a1
+** th.mvneza2,zero,a1
+** th.mveqza3,zero,a1
+** or  a0,a2,a3
+** ret
+*/
+int ConEmv_reg_reg_reg(int x, int y, int z, int n){
+  if (x == y) return z;
+  return n;
+}
+
+/*
+**ConNmv_imm_imm_reg:
+** li  a5,9998336
+** addia4,a0,-1000
+** addia5,a5,1664
+** th.mvneza1,zero,a4
+** th.mveqza5,zero,a4
+** or  a0,a1,a5
+** ret
+*/
+int ConNmv_imm_imm_reg(int x, int y){
+  if (x != 1000) return 1000;
+  return y;
+}
+
+/*
+**ConNmv_imm_reg_reg:
+** addia5,a0,-1000
+** th.mveqza1,zero,a5
+** th.mvneza2,zero,a5
+** or  a0,a1,a2
+** ret
+*/
+int ConNmv_imm_reg_reg(int x, int y, int z){
+  if (x != 1000) return y;
+  return z