* [PATCH] Riscv patterns to optimize away some redundant zero/sign extends.
@ 2017-11-29 22:39 Jim Wilson
0 siblings, 0 replies; only message in thread
From: Jim Wilson @ 2017-11-29 22:39 UTC (permalink / raw)
To: gcc-patches; +Cc: Jim Wilson
This adds some new patterns to eliminate some unecessary zero/sign extends.
This also adds one testcase for each pattern, and one testcase that works
only with the rtx_costs change. There is a lot more work to be done here,
but this does help. With a toolchain/linux kernel/busybox build, I see these
patterns trigger a little over 2300 times.
This was tested with a gcc make check, with no regressions. It was also tested
by building the toolchain/linux kernel/busybox and booting the kernel on a
simulator.
Committed.
gcc/
* config/riscv/riscv.c (SINGLE_SHIFT_COST): New.
(riscv_rtx_costs): Case ZERO_EXTRACT, match new pattern, and return
SINGLE_SHIFT_COST. Case LT and ZERO_EXTEND, likewise. Case ASHIFT,
use SINGLE_SHIFT_COST.
* config/riscv/riscv.md (lshrsi3_zero_extend_1): New.
(lshrsi3_zero_extend_2, lshrsi3_zero_extend_3): New.
gcc/testsuite/
* gcc.target/riscv/riscv.exp: New.
* gcc.target/riscv/zero-extend-1.c: New.
* gcc.target/riscv/zero-extend-2.c: New.
* gcc.target/riscv/zero-extend-3.c: New.
* gcc.target/riscv/zero-extend-4.c: New.
---
gcc/config/riscv/riscv.c | 32 +++++++++++++++++--
gcc/config/riscv/riscv.md | 43 ++++++++++++++++++++++++++
gcc/testsuite/gcc.target/riscv/riscv.exp | 41 ++++++++++++++++++++++++
gcc/testsuite/gcc.target/riscv/zero-extend-1.c | 8 +++++
gcc/testsuite/gcc.target/riscv/zero-extend-2.c | 13 ++++++++
gcc/testsuite/gcc.target/riscv/zero-extend-3.c | 12 +++++++
gcc/testsuite/gcc.target/riscv/zero-extend-4.c | 20 ++++++++++++
7 files changed, 167 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/riscv.exp
create mode 100644 gcc/testsuite/gcc.target/riscv/zero-extend-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zero-extend-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zero-extend-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/zero-extend-4.c
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 279af909a69..5547d68193c 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -1429,6 +1429,8 @@ riscv_extend_cost (rtx op, bool unsigned_p)
/* Implement TARGET_RTX_COSTS. */
+#define SINGLE_SHIFT_COST 1
+
static bool
riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UNUSED,
int *total, bool speed)
@@ -1489,10 +1491,21 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
*total = riscv_binary_cost (x, 1, 2);
return false;
+ case ZERO_EXTRACT:
+ /* This is an SImode shift. */
+ if (outer_code == SET && (INTVAL (XEXP (x, 2)) > 0)
+ && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (x, 2)) == 32))
+ {
+ *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
+ return true;
+ }
+ return false;
+
case ASHIFT:
case ASHIFTRT:
case LSHIFTRT:
- *total = riscv_binary_cost (x, 1, CONSTANT_P (XEXP (x, 1)) ? 4 : 9);
+ *total = riscv_binary_cost (x, SINGLE_SHIFT_COST,
+ CONSTANT_P (XEXP (x, 1)) ? 4 : 9);
return false;
case ABS:
@@ -1504,6 +1517,14 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
return true;
case LT:
+ /* This is an SImode shift. */
+ if (outer_code == SET && GET_MODE (x) == DImode
+ && GET_MODE (XEXP (x, 0)) == SImode)
+ {
+ *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
+ return true;
+ }
+ /* Fall through. */
case LTU:
case LE:
case LEU:
@@ -1601,8 +1622,15 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
*total = COSTS_N_INSNS (1);
return false;
- case SIGN_EXTEND:
case ZERO_EXTEND:
+ /* This is an SImode shift. */
+ if (GET_CODE (XEXP (x, 0)) == LSHIFTRT)
+ {
+ *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
+ return true;
+ }
+ /* Fall through. */
+ case SIGN_EXTEND:
*total = riscv_extend_cost (XEXP (x, 0), GET_CODE (x) == ZERO_EXTEND);
return false;
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 814ff6ec6ad..db4fed48e53 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -1524,6 +1524,49 @@
[(set_attr "type" "shift")
(set_attr "mode" "SI")])
+;; Non-canonical, but can be formed by ree when combine is not successful at
+;; producing one of the two canonical patterns below.
+(define_insn "*lshrsi3_zero_extend_1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
+ (match_operand:SI 2 "const_int_operand"))))]
+ "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0"
+{
+ operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
+
+ return "srliw\t%0,%1,%2";
+}
+ [(set_attr "type" "shift")
+ (set_attr "mode" "SI")])
+
+;; Canonical form for a zero-extend of a logical right shift.
+(define_insn "*lshrsi3_zero_extend_2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extract:DI (match_operand:DI 1 "register_operand" " r")
+ (match_operand 2 "const_int_operand")
+ (match_operand 3 "const_int_operand")))]
+ "(TARGET_64BIT && (INTVAL (operands[3]) > 0)
+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
+{
+ return "srliw\t%0,%1,%3";
+}
+ [(set_attr "type" "shift")
+ (set_attr "mode" "SI")])
+
+;; Canonical form for a zero-extend of a logical right shift when the
+;; shift count is 31.
+(define_insn "*lshrsi3_zero_extend_3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (lt:DI (match_operand:SI 1 "register_operand" " r")
+ (const_int 0)))]
+ "TARGET_64BIT"
+{
+ return "srliw\t%0,%1,31";
+}
+ [(set_attr "type" "shift")
+ (set_attr "mode" "SI")])
+
;;
;; ....................
;;
diff --git a/gcc/testsuite/gcc.target/riscv/riscv.exp b/gcc/testsuite/gcc.target/riscv/riscv.exp
new file mode 100644
index 00000000000..7b1f7e097fb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/riscv.exp
@@ -0,0 +1,41 @@
+# Copyright (C) 2017 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't a RISC-V target.
+if ![istarget riscv*-*-*] then {
+ return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+ "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.target/riscv/zero-extend-1.c b/gcc/testsuite/gcc.target/riscv/zero-extend-1.c
new file mode 100644
index 00000000000..8a7d84ddbca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zero-extend-1.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target { riscv64*-*-* } } } */
+/* { dg-options "-march=rv64gc -mabi=lp64 -O2" } */
+unsigned long
+sub1 (unsigned int i)
+{
+ return i >> 1;
+}
+/* { dg-final { scan-assembler-times "srliw" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zero-extend-2.c b/gcc/testsuite/gcc.target/riscv/zero-extend-2.c
new file mode 100644
index 00000000000..9d30ae29367
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zero-extend-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { riscv64*-*-* } } } */
+/* { dg-options "-march=rv64gc -mabi=lp64 -O2" } */
+void
+sub (unsigned int wc, unsigned long step, unsigned char *start)
+{
+ do
+ {
+ start[--step] = wc;
+ wc >>= 6;
+ }
+ while (step > 1);
+}
+/* { dg-final { scan-assembler-times "sext.w" 0 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zero-extend-3.c b/gcc/testsuite/gcc.target/riscv/zero-extend-3.c
new file mode 100644
index 00000000000..eb3b8d43959
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zero-extend-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { riscv64*-*-* } } } */
+/* { dg-options "-march=rv64gc -mabi=lp64 -O2" } */
+extern int e (void);
+enum { a, b }
+c (void)
+{
+ int d = a;
+ if (e() < 0)
+ d = b;
+ return d;
+}
+/* { dg-final { scan-assembler-times "sext.w" 0 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zero-extend-4.c b/gcc/testsuite/gcc.target/riscv/zero-extend-4.c
new file mode 100644
index 00000000000..d7703a6dfb7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zero-extend-4.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { riscv64*-*-* } } } */
+/* { dg-options "-march=rv64gc -mabi=lp64 -O2" } */
+int a, b, e;
+struct c *d;
+struct c
+{
+ int bins;
+ int binmap[10];
+}
+f(void)
+{
+ for (;;)
+ {
+ e = (unsigned) a >> 3;
+ b = (long) &d[e];
+ if (b)
+ d->binmap[0] = e;
+ }
+}
+/* { dg-final { scan-assembler-times "sext.w" 0 } } */
--
2.14.1
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2017-11-29 22:34 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-29 22:39 [PATCH] Riscv patterns to optimize away some redundant zero/sign extends Jim Wilson
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).