Commit b641d7fc by Adam Nemet Committed by Adam Nemet

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
parent b95d6ac9
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
......
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
......
/* { 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
{
......
/* -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
{
......
/* 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;
}
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