From: "Maciej W. Rozycki" <macro@embecosm.com>
To: gcc-patches@gcc.gnu.org
Cc: Andrew Waterman <andrew@sifive.com>,
Jim Wilson <jim.wilson.gcc@gmail.com>,
Kito Cheng <kito.cheng@gmail.com>,
Palmer Dabbelt <palmer@dabbelt.com>
Subject: [PATCH] RISC-V: Avoid redundant sign-extension for SImode SGE, SGEU, SLE, SLEU
Date: Wed, 3 Aug 2022 10:54:08 +0100 (BST) [thread overview]
Message-ID: <alpine.DEB.2.20.2208021117360.10833@tpp.orcam.me.uk> (raw)
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" } } */
next reply other threads:[~2022-08-03 9:54 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-03 9:54 Maciej W. Rozycki [this message]
2022-08-11 3:26 ` Kito Cheng
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=alpine.DEB.2.20.2208021117360.10833@tpp.orcam.me.uk \
--to=macro@embecosm.com \
--cc=andrew@sifive.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jim.wilson.gcc@gmail.com \
--cc=kito.cheng@gmail.com \
--cc=palmer@dabbelt.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).