This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
SPEC/bzip2 failure at -O3 on HP-UX using hppa64 gcc
- From: Reva Cuthbertson <reva at cup dot hp dot com>
- To: gcc at gcc dot gnu dot org
- Date: Fri, 16 Aug 2002 16:00:54 -0700
- Subject: SPEC/bzip2 failure at -O3 on HP-UX using hppa64 gcc
- Organization: Hewlett-Packard Co.
Hello,
We encountered a problem with the SPEC benchmark bzip2
when compiling it with -O3 on HP-UX using an hppa64 gcc built
from the main branch. The problem appears to be after we inline a
call to bsPutUInt32() in compressStream(). The following rtl:
(zero_extend:DI (lshiftrt:SI (subreg/s/u:SI (reg/v:DI 67) 4)
(const_int 24 [0x18])))
gets converted to:
(lshiftrt:DI (reg/v:DI 67)
(const_int 24 [0x18])
in expand_compound_operation() in combine.c. I think this
optimization should not be happening. In the unoptimized
rtl, it looks like we want to do a left shift of a low part of
a 64-bit register by 24 and then zero out the high order bits.
However, in the optimized rtl, we are just doing the shift
and then putting the result into a 64-bit register. However,
I don't believe that this zeroes out the high order bits in the
register. The code in expand_compound_operation() that does
this optimization is:
/* If we reach here, we want to return a pair of shifts. The inner
shift is a left shift of BITSIZE - POS - LEN bits. The outer
shift is a right shift of BITSIZE - LEN bits. It is arithmetic or
logical depending on the value of UNSIGNEDP.
If this was a ZERO_EXTEND or ZERO_EXTRACT, this pair of shifts will
be converted into an AND of a shift.
We must check for the case where the left shift would have a
negative
count. This can happen in a case like (x >> 31) & 255 on machines
that can't shift by a constant. On those machines, we would first
combine the shift with the AND to produce a variable-position
extraction. Then the constant of 31 would be substituted in to
produce a such a position. */
modewidth = GET_MODE_BITSIZE (GET_MODE (x));
if (modewidth + len >= pos)
tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT :
ASHIFTRT,
GET_MODE (x),
simplify_shift_const
(NULL_RTX, ASHIFT,
GET_MODE (x),
XEXP (x, 0),
modewidth - pos - len),
modewidth - len);
else if (unsignedp && len < HOST_BITS_PER_WIDE_INT)
tem = simplify_and_const_int (NULL_RTX, GET_MODE (x),
simplify_shift_const (NULL_RTX, LSHIFTRT,
GET_MODE (x),
XEXP (x, 0), pos),
((HOST_WIDE_INT) 1 << len) - 1);
else
/* Any other cases we can't handle. */
return x;
modewidth = 64, len = 32, and pos = 0. We hit the first if
statement (if modewidth + len > pos) and make the recursive
call to simplify_shift_const(). This gets rid of the zero_extend.
If I remove this if statement and
execute the "else if (unsignedp && len < HOST_BITS_PER_WIDE_INT)
the spec benchmark works. What I wonder is whether or not we
1) need the first if statement or 2) should flip around the order of
the conditionals in the if statement so that we check if unsignedp
is set and if len < HOST_BITS_PER_WIDE_INT. Any ideas on how
this should be fixed?
Thanks so much!
Reva Cuthberston
reva@cup.hp.com