From: Jeff Law <jeffreyalaw@gmail.com>
To: Xiao Zeng <zengxiao@eswincomputing.com>
Cc: gcc-patches@gcc.gnu.org, research_trasio@irq.a4lg.com,
kito.cheng@gmail.com, zhengyu@eswincomputing.com,
eri-sw-toolchain@eswincomputing.com
Subject: Re: [PATCH V2] [PATCH 3/5] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to 0
Date: Tue, 1 Aug 2023 00:06:45 -0600 [thread overview]
Message-ID: <856935c9-9252-f6c5-a950-4b43a8c156fa@gmail.com> (raw)
In-Reply-To: <20230729091308.29792-1-zengxiao@eswincomputing.com>
On 7/29/23 03:13, 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.
> ---
> gcc/config/riscv/riscv.cc | 144 ++++++++++++++++++
> 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, 414 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 941ea25e1f2..6ac39f63dd7 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -3516,6 +3516,150 @@ 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)
> + {
> + need_eq_ne_p = true;
> + /* 0 + imm */
> + if (GET_CODE (cons) == CONST_INT && cons == const0_rtx
> + && GET_CODE (alt) == CONST_INT && alt != const0_rtx)
A couple nits. Rather than test the GET_CODE (object) == CONST_INT,
instead use CONST_INT_P (object).
Rather than using const0_rtx, use CONST0_RTX (mode). That makes it more
general.
> + {
> + riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
Might as well use "true" rather than "need_eq_ne_p" here and for the
other calls in your new code.
> + /* imm + imm */
> + else if (GET_CODE (cons) == CONST_INT && cons != const0_rtx
> + && GET_CODE (alt) == CONST_INT && alt != const0_rtx)
So same comments on using CONST_INT_P and CONST0_RTX
> + {
> + riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
> + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
> + rtx reg = gen_reg_rtx (mode);
> + rtx temp = GEN_INT (INTVAL (alt) - INTVAL (cons));
> + emit_insn (gen_rtx_SET (reg, temp));
Use force_reg here rather than directly emitting the insn to initialize
"reg". What you're doing works when the difference is small but will
not work when the difference does not fit into a signed 12bit value.
> + /* imm + reg */
> + else if (GET_CODE (cons) == CONST_INT && cons != const0_rtx
> + && GET_CODE (alt) == REG)
Same comments about CONST_INT_P and CONST0_RTX. And instead of using
GET_CODE (object) == REG, use REG_P (object).
> + {
> + /* Optimize for register value of 0. */
> + if (op0 == alt && op1 == const0_rtx)
> + {
> + 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;
> + }
Isn't this only valid for NE? Also use CONST0_RTX in that test.
> + /* 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))
So instead of checking for explicit values, we have SMALL_OPERAND to do
it for us. Also note that for !SMALL_OPERAND we can just force the
value into a register using "force_reg" and all the right things will
happen.
So just add something like this to your original code:
if (!SMALL_OPERAND (INTVAL (cons))
cons = force_reg (mode, cons);
That will result in CONS being either a simple integer constant (when it
is suitable for addi) or a register (all other cases). At that point
you can use it in an arithmetic instruction.
> + /* imm + 0 */
> + else if (GET_CODE (cons) == CONST_INT && cons != const0_rtx
> + && GET_CODE (alt) == CONST_INT && alt == const0_rtx)
> + {
> + riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
> + 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;
> + }
> + /* reg + imm */
> + else if (GET_CODE (cons) == REG
> + && GET_CODE (alt) == CONST_INT && alt != const0_rtx)
> + {
> + /* Optimize for register value of 0. */
> + if (op0 == cons && op1 == const0_rtx)
> + {
> + 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;
> + }
So in this case isn't it only valid for EQ?
> + if (-2048 == INTVAL (alt))
Similar comment as above. When ALT doesn't fit into a SMALL_OPERAND_P,
just force it into a register.
> + /* reg + reg */
> + else if (GET_CODE (cons) == REG && GET_CODE (alt) == REG)
> + {
> + /* Optimize for op0 == cons && op1 == const0_rtx. */
> + if (op0 == cons && op1 == const0_rtx)
> + {
> + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
> + emit_insn (gen_rtx_SET (dest,
> + gen_rtx_IF_THEN_ELSE (mode, cond,
> + CONST0_RTX (mode),
> + alt)));
> + return true;
> + }
> + /* Optimize for op0 == alt && op1 == const0_rtx. */
> + if (op0 == alt && op1 == const0_rtx)
> + {
> + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
> + emit_insn (gen_rtx_SET (dest,
> + gen_rtx_IF_THEN_ELSE (mode, cond, cons,
> + CONST0_RTX (mode))));
> + return true;
> + }
I suspect we need some testing of the code in the two sequences above.
I'd bet one is only valid for EQ and the other for NE.
It's improving considerably.
WRT costing. I'm still seeing some weirdness in how conditional moves
are being costed from the if-converter. I think your patch that set the
cost to COSTS_N_INSNS (0) was just working around a deeper bug in the
costing code. I'm still trying to figure out the best way to clean that up.
jeff
next prev parent reply other threads:[~2023-08-01 6:06 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-29 9:13 Xiao Zeng
2023-08-01 6:06 ` Jeff Law [this message]
2023-08-02 1:39 ` Xiao Zeng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=856935c9-9252-f6c5-a950-4b43a8c156fa@gmail.com \
--to=jeffreyalaw@gmail.com \
--cc=eri-sw-toolchain@eswincomputing.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=kito.cheng@gmail.com \
--cc=research_trasio@irq.a4lg.com \
--cc=zengxiao@eswincomputing.com \
--cc=zhengyu@eswincomputing.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).