Mat Hostetter writes:
> 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.

convert_to_mode uses gen_lowpart for truncation if TRULY_NOOP_TRUNCATION.

> 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.

Agreed but we sort of do this due to this pattern in mips.md:

(define_insn "*lshr32_trunc<mode>"
  [(set (match_operand:SUBDI 0 "register_operand" "=d")
        (truncate:SUBDI
          (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
                       (const_int 32))))]
  "TARGET_64BIT && !TARGET_MIPS16"
  "dsra\t%0,%1,32"
  [(set_attr "type" "shift")
   (set_attr "mode" "<MODE>")])


That said with mode_rep_extended this optimization could now be performed by
the middle-end in simplify-rtx.c:

(truncate:SI (lshiftrt:DI .. 32))
->
(subreg:SI (ashiftrt:DI .. 32) <lowpart>)

if targetm.mode_rep_extended (SImod, DImode) == SIGN_EXTEND.

Adam

Reply via email to