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
This commit is contained in:
parent
bddb7adb44
commit
f88d45dc17
|
@ -1,3 +1,14 @@
|
|||
2016-02-22 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
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.
|
||||
|
||||
2016-02-22 Richard Biener <rguenther@suse.de>
|
||||
Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2016-02-22 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
PR target/69806
|
||||
PR target/54089
|
||||
* gcc.target/sh/pr54089-10.c: New.
|
||||
|
||||
2016-02-20 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/69423
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
/* Check that there are no redundant zero extensions around logical right
|
||||
shifts. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1" } */
|
||||
/* { dg-final { scan-assembler-times "extu" 20 } } */
|
||||
|
||||
/* { dg-final { scan-assembler-times "shll" 2 { target { "! sh2a" && has_dyn_shift } } } } */
|
||||
/* { dg-final { scan-assembler-times "shll" 3 { target { "! sh2a" && "! has_dyn_shift" } } } } */
|
||||
/* { dg-final { scan-assembler-times "movt" 2 { target { ! sh2a } } } } */
|
||||
|
||||
/* { dg-final { scan-assembler-times "bld" 1 { target { sh2a } } } } */
|
||||
/* { dg-final { scan-assembler-times "movt" 1 { target { sh2a } } } } */
|
||||
/* { dg-final { scan-assembler-times "movrt" 1 { target { sh2a } } } } */
|
||||
/* { dg-final { scan-assembler-times "cmp/pz" 1 { target { sh2a } } } } */
|
||||
|
||||
/* { dg-final { scan-assembler-times "shld" 9 { target { has_dyn_shift } } } } */
|
||||
|
||||
void
|
||||
test_0 (unsigned char* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 1;
|
||||
}
|
||||
|
||||
void
|
||||
test_1 (unsigned char* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 2;
|
||||
}
|
||||
|
||||
void
|
||||
test_2 (unsigned char* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 3;
|
||||
}
|
||||
|
||||
void
|
||||
test_3 (unsigned char* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 4;
|
||||
}
|
||||
|
||||
void
|
||||
test_4 (unsigned char* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 5;
|
||||
}
|
||||
|
||||
void
|
||||
test_5 (unsigned char* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 6;
|
||||
}
|
||||
|
||||
void
|
||||
test_6 (unsigned char* x, unsigned int* y)
|
||||
{
|
||||
/* non-SH2A: shll, movt
|
||||
SH2A: bld, movt */
|
||||
y[0] = x[1] >> 7;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
test_100 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 1;
|
||||
}
|
||||
|
||||
void
|
||||
test_101 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 2;
|
||||
}
|
||||
|
||||
void
|
||||
test_102 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 3;
|
||||
}
|
||||
|
||||
void
|
||||
test_103 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 4;
|
||||
}
|
||||
|
||||
void
|
||||
test_104 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 5;
|
||||
}
|
||||
|
||||
void
|
||||
test_105 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 6;
|
||||
}
|
||||
|
||||
void
|
||||
test_106 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 7;
|
||||
}
|
||||
|
||||
void
|
||||
test_107 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 8;
|
||||
}
|
||||
|
||||
void
|
||||
test_108 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 9;
|
||||
}
|
||||
|
||||
void
|
||||
test_109 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 10;
|
||||
}
|
||||
|
||||
void
|
||||
test_110 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 11;
|
||||
}
|
||||
|
||||
void
|
||||
test_111 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 12;
|
||||
}
|
||||
|
||||
void
|
||||
test_112 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 13;
|
||||
}
|
||||
|
||||
void
|
||||
test_113 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
y[0] = x[1] >> 14;
|
||||
}
|
||||
|
||||
void
|
||||
test_114 (unsigned short* x, unsigned int* y)
|
||||
{
|
||||
/* non-SH2A: shll, movt
|
||||
SH2A: cmp/pz, movrt */
|
||||
y[0] = x[1] >> 15;
|
||||
}
|
Loading…
Reference in New Issue