[PATCH] RISC-V: Remove the redundant expressions in the and3.
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
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
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 (&code, &op0, &op1, 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 (&code, &op0, &op1); + 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 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.mv
[PATCH] [RISC-V] Fix riscv_expand_conditional_move.
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 (&code, &op0, &op1); 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) r