]> git.ipfire.org Git - thirdparty/gcc.git/commit
i386: Avoid paradoxical subreg dests in vector zero_extend
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 24 Oct 2023 10:26:45 +0000 (11:26 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Tue, 24 Oct 2023 10:26:45 +0000 (11:26 +0100)
commit58de8e933d19516d1a9de66a617378493ffa29a5
treed8096065ef71078612958eb93fd4e979646f6953
parentcc4779559bea982f9307a8bc1cb017b8eda28d6d
i386: Avoid paradoxical subreg dests in vector zero_extend

For the V2HI -> V2SI zero extension in:

  typedef unsigned short v2hi __attribute__((vector_size(4)));
  typedef unsigned int v2si __attribute__((vector_size(8)));
  v2si f (v2hi x) { return (v2si) {x[0], x[1]}; }

ix86_expand_sse_extend would generate:

   (set (reg:V2HI 102)
        (const_vector:V2HI [(const_int 0 [0])
    (const_int 0 [0])]))
   (set (subreg:V8HI (reg:V2HI 101) 0)
        (vec_select:V8HI
          (vec_concat:V16HI (subreg:V8HI (reg/v:V2HI 99 [ x ]) 0)
                            (subreg:V8HI (reg:V2HI 102) 0))
          (parallel [(const_int 0 [0])
                     (const_int 8 [0x8])
                     (const_int 1 [0x1])
                     (const_int 9 [0x9])
                     (const_int 2 [0x2])
                     (const_int 10 [0xa])
                     (const_int 3 [0x3])
                     (const_int 11 [0xb])])))
  (set (reg:V2SI 100)
       (subreg:V2SI (reg:V2HI 101) 0))
    (expr_list:REG_EQUAL (zero_extend:V2SI (reg/v:V2HI 99 [ x ])))

But using (subreg:V8HI (reg:V2HI 101) 0) as the destination of
the vec_select means that only the low 4 bytes of the destination
are stored.  Only the lower half of reg 100 is well-defined.

Things tend to happen to work if the register allocator ties reg 101
to reg 100.  But it caused problems with the upcoming late-combine pass
because we propagated the set of reg 100 into its uses.

gcc/
* config/i386/i386-expand.cc (ix86_split_mmx_punpck): Allow the
destination to be wider than the sources.  Take the mode from the
first source.
(ix86_expand_sse_extend): Pass the destination directly to
ix86_split_mmx_punpck, rather than using a fresh register that
is half the size.
gcc/config/i386/i386-expand.cc