combine.c (simplify_shift_const_1): Split code to determine shift_mode into ...
* combine.c (simplify_shift_const_1): Split code to determine shift_mode into ... (try_widen_shift_mode): ... here. Allow widening for ASHIFTRT if the new bits shifted in are identical to the old sign bit. testsuite/ * gcc.target/mips/octeon-exts-7.c: New test. * gcc.target/mips/octeon-exts-2.c: Revert previous change. * gcc.target/mips/octeon-exts-5.c: Likewise. From-SVN: r149778
This commit is contained in:
parent
b95d6ac9ca
commit
b641d7fca3
@ -1,3 +1,10 @@
|
||||
2009-07-18 Adam Nemet <anemet@caviumnetworks.com>
|
||||
|
||||
* combine.c (simplify_shift_const_1): Split code to determine
|
||||
shift_mode into ...
|
||||
(try_widen_shift_mode): ... here. Allow widening for ASHIFTRT if the
|
||||
new bits shifted in are identical to the old sign bit.
|
||||
|
||||
2009-07-18 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR c/40787
|
||||
|
@ -8982,6 +8982,42 @@ merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* A helper to simplify_shift_const_1 to determine the mode we can perform
|
||||
the shift in. The original shift operation CODE is performed on OP in
|
||||
ORIG_MODE. Return the wider mode MODE if we can perform the operation
|
||||
in that mode. Return ORIG_MODE otherwise. */
|
||||
|
||||
static enum machine_mode
|
||||
try_widen_shift_mode (enum rtx_code code, rtx op,
|
||||
enum machine_mode orig_mode, enum machine_mode mode)
|
||||
{
|
||||
if (orig_mode == mode)
|
||||
return mode;
|
||||
gcc_assert (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (orig_mode));
|
||||
|
||||
/* In general we can't perform in wider mode for right shift and rotate. */
|
||||
switch (code)
|
||||
{
|
||||
case ASHIFTRT:
|
||||
/* We can still widen if the bits brought in from the left are identical
|
||||
to the sign bit of ORIG_MODE. */
|
||||
if (num_sign_bit_copies (op, mode)
|
||||
> (unsigned) (GET_MODE_BITSIZE (mode)
|
||||
- GET_MODE_BITSIZE (orig_mode)))
|
||||
return mode;
|
||||
/* fall through */
|
||||
case LSHIFTRT:
|
||||
case ROTATE:
|
||||
return orig_mode;
|
||||
|
||||
case ROTATERT:
|
||||
gcc_unreachable ();
|
||||
|
||||
default:
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
/* Simplify a shift of VAROP by COUNT bits. CODE says what kind of shift.
|
||||
The result of the shift is RESULT_MODE. Return NULL_RTX if we cannot
|
||||
simplify it. Otherwise, return a simplified value.
|
||||
@ -9041,13 +9077,7 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
|
||||
count = bitsize - count;
|
||||
}
|
||||
|
||||
/* We need to determine what mode we will do the shift in. If the
|
||||
shift is a right shift or a ROTATE, we must always do it in the mode
|
||||
it was originally done in. Otherwise, we can do it in MODE, the
|
||||
widest mode encountered. */
|
||||
shift_mode
|
||||
= (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
|
||||
? result_mode : mode);
|
||||
shift_mode = try_widen_shift_mode (code, varop, result_mode, mode);
|
||||
|
||||
/* Handle cases where the count is greater than the size of the mode
|
||||
minus 1. For ASHIFT, use the size minus one as the count (this can
|
||||
@ -9645,14 +9675,7 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
|
||||
break;
|
||||
}
|
||||
|
||||
/* We need to determine what mode to do the shift in. If the shift is
|
||||
a right shift or ROTATE, we must always do it in the mode it was
|
||||
originally done in. Otherwise, we can do it in MODE, the widest mode
|
||||
encountered. The code we care about is that of the shift that will
|
||||
actually be done, not the shift that was originally requested. */
|
||||
shift_mode
|
||||
= (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
|
||||
? result_mode : mode);
|
||||
shift_mode = try_widen_shift_mode (code, varop, result_mode, mode);
|
||||
|
||||
/* We have now finished analyzing the shift. The result should be
|
||||
a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places. If
|
||||
|
@ -1,3 +1,9 @@
|
||||
2009-07-18 Adam Nemet <anemet@caviumnetworks.com>
|
||||
|
||||
* gcc.target/mips/octeon-exts-7.c: New test.
|
||||
* gcc.target/mips/octeon-exts-2.c: Revert previous change.
|
||||
* gcc.target/mips/octeon-exts-5.c: Likewise.
|
||||
|
||||
2009-07-18 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR testsuite/40798
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -march=octeon -meb -dp" } */
|
||||
/* Don't match exts in sign-extension. */
|
||||
/* { dg-final { scan-assembler-times "\texts\t\[^\\n\]*extv" 4 } } */
|
||||
/* { dg-options "-O -march=octeon -meb" } */
|
||||
/* { dg-final { scan-assembler-times "\texts\t" 4 } } */
|
||||
|
||||
struct bar
|
||||
{
|
||||
|
@ -1,8 +1,7 @@
|
||||
/* -mel version of octeon-exts-2.c. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -march=octeon -mel -dp" } */
|
||||
/* Don't match exts in sign-extension. */
|
||||
/* { dg-final { scan-assembler-times "\texts\t\[^\\n\]*extv" 4 } } */
|
||||
/* { dg-options "-O -march=octeon -mel" } */
|
||||
/* { dg-final { scan-assembler-times "\texts\t" 4 } } */
|
||||
|
||||
struct bar
|
||||
{
|
||||
|
17
gcc/testsuite/gcc.target/mips/octeon-exts-7.c
Normal file
17
gcc/testsuite/gcc.target/mips/octeon-exts-7.c
Normal file
@ -0,0 +1,17 @@
|
||||
/* Remove the redundant sign-extension after the sign-extraction. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -march=octeon -mgp64" } */
|
||||
/* { dg-final { scan-assembler-times "\texts\t" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "sll|sra" } } */
|
||||
|
||||
struct bar
|
||||
{
|
||||
long long a:18;
|
||||
long long b:14;
|
||||
};
|
||||
|
||||
NOMIPS16 int
|
||||
f1 (struct bar *s)
|
||||
{
|
||||
return s->b;
|
||||
}
|
Loading…
Reference in New Issue
Block a user