[Patch, RTL] Eliminate redundant vec_select moves.

H.J. Lu hjl.tools@gmail.com
Tue Dec 10 18:21:00 GMT 2013


On Tue, Dec 10, 2013 at 9:57 AM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>> On Tue, Dec 10, 2013 at 8:05 AM, Kirill Yukhin <kirill.yukhin@gmail.com> wrote:
>>> On 09 Dec 14:08, H.J. Lu wrote:
>>>>
>>>> There are no regressions on Linux/x86-64 with -m32 and -m64.
>>>> Can you check if it improves code quality on x886?
>>>
>>> As second thought. If Tejas and Richard are right and it is simply incorrect
>>> to check any offsets in this hook, may be we can end up with patch in the
>>> bottom?
>>
>> What is wrong to pass the correct offset to
>> CANNOT_CHANGE_MODE_CLASS?  Backends are free to
>> ignore it.
>
> The point is that:
>
>>> -      /* Vector registers do not support subreg with nonzero offsets, which
>>> -        are otherwise valid for integer registers.  Since we can't see
>>> -        whether we have a nonzero offset from here, prohibit all
>>> -         nonparadoxical subregs changing size.  */
>>> -      if (GET_MODE_SIZE (to) < GET_MODE_SIZE (from))
>>> -       return true;
>
> seems to be trying to reject things like (subreg:SF (reg:V4SF X) 1),
> which is always invalid for a single-register V4SF.  See:

That is correct.

>     http://gcc.gnu.org/ml/gcc-patches/2013-12/msg00824.html
>
> for the longer version.

In all places where CANNOT_CHANGE_MODE_CLASS is used,
only mode_change_ok, record_subregs_of_mode and inherit_piecemeal_p
don't have the known subreg offset.  In all other places, we know
what exactly the subreg offset is. When the subreg offset is passed
to CANNOT_CHANGE_MODE_CLASS, a backend can have

(subreg:DI (match_operand:V4SF 1 "register_operand" "x,x") 0)

in patterns.  I pushed hjl/subreg branch to GCC git repo with
a new pattern:


(define_insn "*mov<VMOVE:mode><VMOVE_SWI48:mode>_subreg"
 [(set (match_operand:VMOVE_SWI48 0 "nonimmediate_operand"           "=rxm")
       (subreg:VMOVE_SWI48 (match_operand:VMOVE 1 "register_operand" "x") 0))]
 ""
{
#if 1
  /* Help check where the subreg pattern is used.  */
  debug_rtx (insn);
  abort ();
#else
  /* Handle broken assemblers that require movd instead of movq.  */
  if (<VMOVE_SWI48:MODE>mode == SImode
      || (!HAVE_AS_IX86_INTERUNIT_MOVQ
          && (GENERAL_REG_P (operands[0]))))
    return "%vmovd\t{%x1, %0|%0, %x1}";
  return "%vmovq\t{%x1, %0|%0, %1x}";
#endif
}
  [(set_attr "type" "ssemov")
   (set_attr "prefix" "maybe_vex")
   (set_attr "mode" "<VMOVE_SWI48:MODE>")])

I ran GCC testsuites with all languages enabled.  This pattern
is triggered 1178 times.  I checked a few of them.  The new patten
leads to reg-reg move instead of mem-reg load.


-- 
H.J.



More information about the Gcc-patches mailing list