DJ Delorie <[EMAIL PROTECTED]> writes:

> The r8c/m16c family cannot shift by more than 16 bits at a time ever,
> or 8 bits at a time with constant shifts.  So, to do a variable number
> of shift on a 32 bit value, it needs to emit a conditional, turning
> the attached example into this:
> 
> i = 0xfffff;
> if (j >= 16)
>   {
>     i >>= 8;
>     i >>= 8;
>     j -= 16;
>   }
> ...
> 
> Combine (rightfully) knows that i becomes the constant 0xf and
> replaces the two constant shifts with it.  However, it doesn't update
> the life information.  So, we have a basic block (#3 below) which has
> register 28 live, but being assigned (i.e. it's really dead).  GCC
> notices this later, and dies.
> 
> Ideas?

The problem is presumably arising from the REG_EQUAL notes.  Where are
those being generated?  Why does this case not arise for other targets?

The only fully correct fix that I see in combine is for combine to
notice that it is replacing the first use of a register which is live
at the start of the block.  In that case, it should set the
appropriate bit in refresh_blocks.  The place to do this would
probably be somewhere around the calls do distribute_notes in
try_combine.  But I'm not sure that's really the right fix.

Ian

Reply via email to