Commit 08539f3e by Jim Wilson Committed by Jim Wilson

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 <andrew@sifive.com>

From-SVN: r255257
parent 591996ba
2017-11-29 Jim Wilson <jimw@sifive.com>
Andrew Waterman <andrew@sifive.com>
* 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 <julia.koval@intel.com> 2017-11-29 Julia Koval <julia.koval@intel.com>
* config/i386/avx512vbmi2intrin.h (_mm512_shldv_epi16, * config/i386/avx512vbmi2intrin.h (_mm512_shldv_epi16,
...@@ -1429,6 +1429,8 @@ riscv_extend_cost (rtx op, bool unsigned_p) ...@@ -1429,6 +1429,8 @@ riscv_extend_cost (rtx op, bool unsigned_p)
/* Implement TARGET_RTX_COSTS. */ /* Implement TARGET_RTX_COSTS. */
#define SINGLE_SHIFT_COST 1
static bool static bool
riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UNUSED, riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UNUSED,
int *total, bool speed) int *total, bool speed)
...@@ -1489,10 +1491,21 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN ...@@ -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); *total = riscv_binary_cost (x, 1, 2);
return false; 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 ASHIFT:
case ASHIFTRT: case ASHIFTRT:
case LSHIFTRT: 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; return false;
case ABS: case ABS:
...@@ -1504,6 +1517,14 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN ...@@ -1504,6 +1517,14 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
return true; return true;
case LT: 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 LTU:
case LE: case LE:
case LEU: case LEU:
...@@ -1601,8 +1622,15 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN ...@@ -1601,8 +1622,15 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
*total = COSTS_N_INSNS (1); *total = COSTS_N_INSNS (1);
return false; return false;
case SIGN_EXTEND:
case ZERO_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); *total = riscv_extend_cost (XEXP (x, 0), GET_CODE (x) == ZERO_EXTEND);
return false; return false;
......
...@@ -1524,6 +1524,49 @@ ...@@ -1524,6 +1524,49 @@
[(set_attr "type" "shift") [(set_attr "type" "shift")
(set_attr "mode" "SI")]) (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")])
;; ;;
;; .................... ;; ....................
;; ;;
......
2017-11-29 Jim Wilson <jimw@sifive.com>
* 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 <dmalcolm@redhat.com> 2017-11-29 David Malcolm <dmalcolm@redhat.com>
* g++.dg/cpp1y/static_assert3.C: New test case. * g++.dg/cpp1y/static_assert3.C: New test case.
......
# 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
/* { 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 } } */
/* { 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 } } */
/* { 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 } } */
/* { 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 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment