This is the mail archive of the gcc@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]
Other format: [Raw text]

SPEC/bzip2 failure at -O3 on HP-UX using hppa64 gcc


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






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