aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/sh
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2016-02-22 13:33:31 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2016-02-22 13:33:31 +0000
commitf88d45dc171e59e120817912115550b943c30b22 (patch)
treeedb2f6b914dc2e288c537e24bcb365233f139a86 /gcc/config/sh
parentbddb7adb4411ec4c9653e61accb3db25e3b2c405 (diff)
downloadgcc-f88d45dc171e59e120817912115550b943c30b22.zip
gcc-f88d45dc171e59e120817912115550b943c30b22.tar.gz
gcc-f88d45dc171e59e120817912115550b943c30b22.tar.bz2
re PR rtl-optimization/69806 ([SH] Combine doesn't see constant)
gcc/ PR target/69806 PR target/54089 * config/sh/sh.c (sh_lshrsi_clobbers_t_reg_p, sh_dynamicalize_shift_p): Handle negative shift counts. * config/sh/sh.md (ashlsi3, lshrsi3_n, lshrsi3_n_clobbers_t): Don't use force_reg on the shift constant. (lshrsi3): Likewise. Expand into lshrsi3_n* instead of lshrsi3_d. (lshrsi3_d): Handle negative shift counts. gcc/testsuite/ PR target/69806 PR target/54089 * gcc.target/sh/pr54089-10.c: New. From-SVN: r233601
Diffstat (limited to 'gcc/config/sh')
-rw-r--r--gcc/config/sh/sh.c6
-rw-r--r--gcc/config/sh/sh.md24
2 files changed, 20 insertions, 10 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 0b18ce5..8c8fe3c 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -3259,7 +3259,8 @@ sh_lshrsi_clobbers_t_reg_p (rtx shift_amount)
{
gcc_assert (CONST_INT_P (shift_amount));
- const int shift_amount_i = INTVAL (shift_amount) & 31;
+ /* For right shifts the constant might be negative. */
+ const int shift_amount_i = std::abs (INTVAL (shift_amount)) & 31;
/* Special case for shift count of 31: use shll-movt sequence. */
if (shift_amount_i == 31)
@@ -3278,7 +3279,8 @@ sh_dynamicalize_shift_p (rtx count)
{
gcc_assert (CONST_INT_P (count));
- const int shift_amount_i = INTVAL (count) & 31;
+ /* For right shifts the constant might be negative. */
+ const int shift_amount_i = std::abs (INTVAL (count)) & 31;
int insn_count;
/* For left and right shifts, there are shorter 2 insn sequences for
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 9fa835b..c0a9249c 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -5011,7 +5011,10 @@ label:
}
if (TARGET_DYNSHIFT
&& CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
- operands[2] = force_reg (SImode, operands[2]);
+ {
+ /* Don't force the constant into a reg yet. Some other optimizations
+ might not see through the reg that holds the shift count. */
+ }
/* If the ashlsi3_* insn is going to clobber the T_REG it must be
expanded here. */
@@ -5567,9 +5570,12 @@ label:
if (TARGET_DYNSHIFT
&& CONST_INT_P (operands[2]) && sh_dynamicalize_shift_p (operands[2]))
{
- rtx neg_count = force_reg (SImode,
- gen_int_mode (- INTVAL (operands[2]), SImode));
- emit_insn (gen_lshrsi3_d (operands[0], operands[1], neg_count));
+ /* Don't force the constant into a reg yet. Some other optimizations
+ might not see through the reg that holds the shift count. */
+ if (sh_lshrsi_clobbers_t_reg_p (operands[2]))
+ emit_insn (gen_lshrsi3_n_clobbers_t (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_lshrsi3_n (operands[0], operands[1], operands[2]));
DONE;
}
@@ -5621,6 +5627,10 @@ label:
&& ! sh_lshrsi_clobbers_t_reg_p (operands[2])"
[(const_int 0)]
{
+ /* The shift count const_int is a negative value for all dynamic
+ right shift insns. */
+ operands[2] = GEN_INT (- INTVAL (operands[2]));
+
if (satisfies_constraint_P27 (operands[2]))
{
/* This will not be done for a shift amount of 1, because it would
@@ -5679,8 +5689,7 @@ label:
{
/* If this pattern was picked and dynamic shifts are supported, switch
to dynamic shift pattern before reload. */
- operands[2] = force_reg (SImode,
- gen_int_mode (- INTVAL (operands[2]), SImode));
+ operands[2] = GEN_INT (- INTVAL (operands[2]));
emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
}
else
@@ -5711,8 +5720,7 @@ label:
{
/* If this pattern was picked and dynamic shifts are supported, switch
to dynamic shift pattern before reload. */
- operands[2] = force_reg (SImode,
- gen_int_mode (- INTVAL (operands[2]), SImode));
+ operands[2] = GEN_INT (- INTVAL (operands[2]));
emit_insn (gen_lshrsi3_d (operands[0], operands[1], operands[2]));
}
else