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