This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to simplify_shift_const
- To: gcc-patches at gcc dot gnu dot org
- Subject: Patch to simplify_shift_const
- From: Richard Sandiford <r dot sandiford at redhat dot com>
- Date: 10 Sep 2001 18:57:11 +0100
A question and patch to do with the way simplify_binary_operator() and
simplify_shift_const() optimize shifts.
Both functions do a range change on the shift value and truncate it if
SHIFT_COUNT_TRUNCATED is defined. s_b_o() does the truncation first and
treats shifts by the mode size as undefined. s_s_b() doesn't treat
shifts by the mode size as undefined, and does the truncation after the
range check (so the truncation only affects the case when the shift ==
the mode size). Does anyone know if it's supposed to be like that?
The first version seems to make more sense on the face of it.
The switch handler for shifts in simplify_binary_operator() says:
-----------------------------------------------------------------------
case LSHIFTRT: case ASHIFTRT:
case ASHIFT:
case ROTATE: case ROTATERT:
#ifdef SHIFT_COUNT_TRUNCATED
if (SHIFT_COUNT_TRUNCATED)
l2 &= (GET_MODE_BITSIZE (mode) - 1), h2 = 0;
#endif
if (h2 != 0 || l2 >= GET_MODE_BITSIZE (mode))
return 0;
-----------------------------------------------------------------------
where l2 is unsigned. simplify_shift_const() says:
-----------------------------------------------------------------------
/* If we were given an invalid count, don't do anything except exactly
what was requested. */
if (input_count < 0 || input_count > (int) GET_MODE_BITSIZE (mode))
{
if (x)
return x;
return gen_rtx_fmt_ee (code, mode, varop, GEN_INT (input_count));
}
count = input_count;
/* Make sure and truncate the "natural" shift on the way in. We don't
want to do this inside the loop as it makes it more difficult to
combine shifts. */
#ifdef SHIFT_COUNT_TRUNCATED
if (SHIFT_COUNT_TRUNCATED)
count %= GET_MODE_BITSIZE (mode);
#endif
-----------------------------------------------------------------------
The difference in bounds checking is causing compiled/950612-1.c to fail
on h8300-elf. So if the difference isn't intentional, is it OK to
install the following? It fixes the h8300 failure and i386 linux still
bootstraps.
* combine.c (simplify_shift_const): Treat shifts by the mode
size as undefined.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.233
diff -u -p -d -r1.233 combine.c
--- combine.c 2001/08/28 00:59:31 1.233
+++ combine.c 2001/09/10 17:07:27
@@ -8825,7 +8825,7 @@ simplify_shift_const (x, code, result_mo
/* If we were given an invalid count, don't do anything except exactly
what was requested. */
- if (input_count < 0 || input_count > (int) GET_MODE_BITSIZE (mode))
+ if (input_count < 0 || input_count >= (int) GET_MODE_BITSIZE (mode))
{
if (x)
return x;