public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Kito Cheng <kito.cheng@gmail.com>
To: "Maciej W. Rozycki" <macro@embecosm.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>,
	Andrew Waterman <andrew@sifive.com>
Subject: Re: [PATCH] RISC-V: Avoid redundant sign-extension for SImode SGE, SGEU, SLE, SLEU
Date: Thu, 11 Aug 2022 11:26:13 +0800	[thread overview]
Message-ID: <CA+yXCZDwfPKSueU+QtiTz+cwiauYb0GmEW5tbwKvqKiiJEsiqg@mail.gmail.com> (raw)
In-Reply-To: <alpine.DEB.2.20.2208021117360.10833@tpp.orcam.me.uk>

LGTM, but with a nit, I don't get set.w but get an andi like below, so
maybe we should also scan-assembler-not andi? feel free to commit that
directly with that fix

```asm
sleu:
       sgtu    a0,a0,a1        # 9     [c=4 l=4]  *sgtu_disi
       xori    a0,a0,1 # 10    [c=4 l=4]  *xorsi3_internal/1
       andi    a0,a0,1 # 16    [c=4 l=4]  anddi3/1
       ret             # 25    [c=0 l=4]  simple_return
```

On Wed, Aug 3, 2022 at 5:54 PM Maciej W. Rozycki <macro@embecosm.com> wrote:
>
> We produce inefficient code for some synthesized SImode conditional set
> operations (i.e. ones that are not directly implemented in hardware) on
> RV64.  For example a piece of C code like this:
>
> int
> sleu (unsigned int x, unsigned int y)
> {
>   return x <= y;
> }
>
> gets compiled (at `-O2') to this:
>
> sleu:
>         sgtu    a0,a0,a1        # 9     [c=4 l=4]  *sgtu_disi
>         xori    a0,a0,1         # 10    [c=4 l=4]  *xorsi3_internal/1
>         sext.w  a0,a0           # 16    [c=4 l=4]  extendsidi2/0
>         ret                     # 25    [c=0 l=4]  simple_return
>
> This is because the middle end expands a SLEU operation missing from
> RISC-V hardware into a sequence of a SImode SGTU operation followed by
> an explicit SImode XORI operation with immediate 1.  And while the SGTU
> machine instruction (alias SLTU with the input operands swapped) gives a
> properly sign-extended 32-bit result which is valid both as a SImode or
> a DImode operand the middle end does not see that through a SImode XORI
> operation, because we tell the middle end that the RISC-V target (unlike
> MIPS) may hold values in DImode integer registers that are valid for
> SImode operations even if not properly sign-extended.
>
> However the RISC-V psABI requires that 32-bit function arguments and
> results passed in 64-bit integer registers be properly sign-extended, so
> this is explicitly done at the conclusion of the function.
>
> Fix this by making the backend use a sequence of a DImode SGTU operation
> followed by a SImode SEQZ operation instead.  The latter operation is
> known by the middle end to produce a properly sign-extended 32-bit
> result and therefore combine gets rid of the sign-extension operation
> that follows and actually folds it into the very same XORI machine
> operation resulting in:
>
> sleu:
>         sgtu    a0,a0,a1        # 9     [c=4 l=4]  *sgtu_didi
>         xori    a0,a0,1         # 16    [c=4 l=4]  xordi3/1
>         ret                     # 25    [c=0 l=4]  simple_return
>
> instead (although the SEQZ alias SLTIU against immediate 1 machine
> instruction would equally do and is actually retained at `-O0').  This
> is handled analogously for the remaining synthesized operations of this
> kind, i.e. `SLE', `SGEU', and `SGE'.
>
>         gcc/
>         * config/riscv/riscv.cc (riscv_emit_int_order_test): Use EQ 0
>         rather that XOR 1 for LE and LEU operations.
>
>         gcc/testsuite/
>         * gcc.target/riscv/sge.c: New test.
>         * gcc.target/riscv/sgeu.c: New test.
>         * gcc.target/riscv/sle.c: New test.
>         * gcc.target/riscv/sleu.c: New test.
> ---
> Hi,
>
>  Regression-tested with the `riscv64-linux-gnu' target.  OK to apply?
>
>   Maciej
> ---
>  gcc/config/riscv/riscv.cc             |    4 ++--
>  gcc/testsuite/gcc.target/riscv/sge.c  |   11 +++++++++++
>  gcc/testsuite/gcc.target/riscv/sgeu.c |   11 +++++++++++
>  gcc/testsuite/gcc.target/riscv/sle.c  |   11 +++++++++++
>  gcc/testsuite/gcc.target/riscv/sleu.c |   11 +++++++++++
>  5 files changed, 46 insertions(+), 2 deletions(-)
>
> gcc-riscv-int-order-inv-seqz.diff
> Index: gcc/gcc/config/riscv/riscv.cc
> ===================================================================
> --- gcc.orig/gcc/config/riscv/riscv.cc
> +++ gcc/gcc/config/riscv/riscv.cc
> @@ -2500,9 +2500,9 @@ riscv_emit_int_order_test (enum rtx_code
>         }
>        else if (invert_ptr == 0)
>         {
> -         rtx inv_target = riscv_force_binary (GET_MODE (target),
> +         rtx inv_target = riscv_force_binary (word_mode,
>                                                inv_code, cmp0, cmp1);
> -         riscv_emit_binary (XOR, target, inv_target, const1_rtx);
> +         riscv_emit_binary (EQ, target, inv_target, const0_rtx);
>         }
>        else
>         {
> Index: gcc/gcc/testsuite/gcc.target/riscv/sge.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/sge.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" } } */
> +
> +int
> +sge (int x, int y)
> +{
> +  return x >= y;
> +}
> +
> +/* { dg-final { scan-assembler-not "sext\\.w" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/sgeu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/sgeu.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" } } */
> +
> +int
> +sgeu (unsigned int x, unsigned int y)
> +{
> +  return x >= y;
> +}
> +
> +/* { dg-final { scan-assembler-not "sext\\.w" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/sle.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/sle.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" } } */
> +
> +int
> +sle (int x, int y)
> +{
> +  return x <= y;
> +}
> +
> +/* { dg-final { scan-assembler-not "sext\\.w" } } */
> Index: gcc/gcc/testsuite/gcc.target/riscv/sleu.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.target/riscv/sleu.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target rv64 } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" } } */
> +
> +int
> +sleu (unsigned int x, unsigned int y)
> +{
> +  return x <= y;
> +}
> +
> +/* { dg-final { scan-assembler-not "sext\\.w" } } */

  reply	other threads:[~2022-08-11  3:26 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-03  9:54 Maciej W. Rozycki
2022-08-11  3:26 ` Kito Cheng [this message]
2022-08-12 22:01   ` Maciej W. Rozycki
2022-11-25 14:07     ` [PING][PATCH] " Maciej W. Rozycki
2022-11-28 14:50       ` Jeff Law
2022-11-28 15:38         ` Maciej W. Rozycki
2022-11-28 16:15           ` Jeff Law
2022-11-28 17:44             ` [PATCH v2] " Maciej W. Rozycki
2022-11-28 18:07               ` Jeff Law
2022-11-28 19:41                 ` Maciej W. Rozycki

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=CA+yXCZDwfPKSueU+QtiTz+cwiauYb0GmEW5tbwKvqKiiJEsiqg@mail.gmail.com \
    --to=kito.cheng@gmail.com \
    --cc=andrew@sifive.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=macro@embecosm.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).