From: Jim Wilson Date: Wed, 29 Nov 2017 22:14:17 +0000 (+0000) Subject: Riscv patterns to optimize away some redundant zero/sign extends. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=08539f3e949c37dcfe6e128d78c527db47cc609d;p=gcc.git Riscv patterns to optimize away some redundant zero/sign extends. 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. Co-Authored-By: Andrew Waterman From-SVN: r255257 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 96f27abc3f0..877a4e8e248 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2017-11-29 Jim Wilson + Andrew Waterman + + * 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. + 2017-11-29 Julia Koval * config/i386/avx512vbmi2intrin.h (_mm512_shldv_epi16, 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/ChangeLog b/gcc/testsuite/ChangeLog index 1b6e93a7986..5f237ae78c2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2017-11-29 Jim Wilson + + * 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. + 2017-11-29 David Malcolm * g++.dg/cpp1y/static_assert3.C: New test case. 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 +# . + +# 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 } } */