public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] RISC-V: Avoid redundant sign-extension for SImode SGE, SGEU,  SLE, SLEU
@ 2022-08-03  9:54 Maciej W. Rozycki
  2022-08-11  3:26 ` Kito Cheng
  0 siblings, 1 reply; 10+ messages in thread
From: Maciej W. Rozycki @ 2022-08-03  9:54 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Waterman, Jim Wilson, Kito Cheng, Palmer Dabbelt

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" } } */

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-11-28 19:41 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-03  9:54 [PATCH] RISC-V: Avoid redundant sign-extension for SImode SGE, SGEU, SLE, SLEU Maciej W. Rozycki
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

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).