This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch to simplify_shift_const



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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]