Adam Nemet <adambne...@gmail.com> writes:

> Ian Lance Taylor <i...@google.com> writes:
> > Mat Hostetter <mhostet...@tilera.com> writes:
> >
> >> Since the high bits are already zero, that would be less efficient on
> >> most platforms, so guarding it with something like this would probably
> >> be smarter:
> >>
> >>   if (targetm.mode_rep_extended (mode, GET_MODE(x)) == SIGN_EXTEND)
> >>     return simplify_gen_unary (TRUNCATE, mode, x, GET_MODE (x));
> >>
> >> I'm happy to believe I'm doing something wrong in my back end, but I'm
> >> not sure what that would be.  I could also believe these are obscure
> >> edge cases no one cared about before.  Any tips would be appreciated.
> >
> > Interesting.  I think you are in obscure edge case territory.  Your
> > suggestion makes sense to me, and in fact it should probably be put
> > into gen_lowpart_common.
> 
> FWIW, I disagree.  Firstly, mode_rep_extended is a special case of
> !TRULY_NOOP_TRUNCATION so the above check should use that.  Secondly, in
> MIPS we call gen_lowpart to convert DI to SI when we know it's safe.  In
> this case we always want a subreg not a truncate for better code.  So I
> don't think gen_lowpart_common is the right place to fix this.
>
> I think the right fix is to call convert_to_mode or convert_move in the
> expansion code which ensure the proper truncation.

That would yield correct code, but wouldn't it throw away the fact
that the high bits are already known to be zero, and yield redundant
zero-extension on some platforms?  I'm guessing that's why the code was
originally written to call convert_lowpart rather than convert_to_mode.

And just to add a minor wrinkle: for the widen_bswap case, which
produces (bswap64 (x) >> 32), the optimal thing is actually to use
ashiftrt instead of lshiftrt when targetm.mode_rep_extended says
SIGN_EXTEND, and then call convert_lowpart as now.

-Mat

Reply via email to