[PATCH] PR middle-end/17151: x >> (y % 64) not optimized on alpha

Roger Sayle roger@eyesopen.com
Fri Sep 24 02:00:00 GMT 2004


The following simple patch is fix for PR middle-end/17151 which is
a missed optimization.  Not a critical bug, but low hanging fruit in
my efforts to close middle-end PRs.

The symptom is that GCC is failing to optimize away an unnecessary
bit-wise AND operation on SHIFT_COUNT_TRUNCATED targets.  For example,
on the alpha (which is a 64-bit target), we simplify "x >> (y & 127)"
to "x >> y", but mysteriously "x >> (y & 63)" retains the AND before
the SHIFT.

unsigned long f(unsigned long x, unsigned long y)
{
  return x >> (y % 64);
}

f:	and $17,63,$17
	srl $16,$17,$0
	ret $31,($26),1


The problem turns out to be a bogus test in the depths of combine.c.
The routine force_to_mode is used to simplify an RTL expression when
we know that only a subset of the bits of the result are relevant.
In this case, we try and simplify "(and:DI (reg:DI) (const_int 63))"
stating that we're only interested in the mask 63 of the result.
This is then triggers an overly eager early exit test, that returns
the original expression if the high bits are already zero?!  We really
don't care about the upper bits, and this check prevents us from
simplifying the expression further.  It should also explain why we
optimize away "x & 127", as we can't prove all the high bits are zero
and proceed to optimize the entire and away.  The simple fix is to
just delete this bogus counter-optimization, which has been in modern
CVS since it's inception, revision 1.1.

f:      srl $16,$17,$0
        ret $31,($26),1

The following patch has been tested on both alphaev67-dec-osf5.1 with
a bootstrap of all languages except java, and i686-pc-linux-gnu with
all default languages, and on both systems regression tested with a
top-level "make -k check" with no new failures.  Mainline libjava
currently fails to build on Tru64 with an "Arg list too long" system
error invoking libtool to build libgcj.la.

Ok for mainline?



2004-09-23  Roger Sayle  <roger@eyesopen.com>

	PR middle-end/17151
	* combine.c (force_to_mode): Remove dubious early return test that
	inhibits further optimization.


Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.454
diff -c -3 -p -r1.454 combine.c
*** combine.c	9 Sep 2004 21:57:50 -0000	1.454
--- combine.c	21 Sep 2004 16:36:45 -0000
*************** force_to_mode (rtx x, enum machine_mode
*** 6904,6914 ****
        && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
      return gen_lowpart (mode, x);

-   /* If we aren't changing the mode, X is not a SUBREG, and all zero bits in
-      MASK are already known to be zero in X, we need not do anything.  */
-   if (GET_MODE (x) == mode && code != SUBREG && (~mask & nonzero) == 0)
-     return x;
-
    switch (code)
      {
      case CLOBBER:
--- 6904,6909 ----


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833



More information about the Gcc-patches mailing list