This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Regarding bug 22480, vectorisation of shifts


Uros Bizjak wrote (privately, but I forwarded to GCC in order to get help):

Hello Paolo!

I was looking at PR middle-end/22480 if there is something to fix at the i386 backend. However, there is no documentation at all regarding vec_shl_<mode> and vec_shr_<mode> builtins.


Heh, I'm quite at a loss regarding PR22480. I don't know exactly what to do because i386 does not support, e.g. { 2, 4 } << { 1, 2 } (which would give {4, 16} as a result). There is indeed a back-end problem, because ashl<mode>3 is supposed to have two operands of the same mode, not one vector and one SI!

On the other hand, I'm not keen on using vec_shl_<mode> because these shift the *whole* register, not each byte/word/dword. i.e. { 0x40000000, 0x80000000 } << 2 = { 2, 0 } which is not really what is expected.

One simple way to fix the PR could be *not* to define ashl<mode>3 insns for i386. These however would lose vectorization of a shift by constant.

Another way could be to

1) in the vectorizer, check in the optab if the predicate for each operand of an insn accepts a register. If not, refuse vectorization if the corresponding gimple operand is not constant.

2) and add a new predicate to i386 that only accepts CONST_VECTORs whose items are all the same. Make ashl<mode>3 use it, with a define_expand, and add a new insn which is the old ashl<mode>3:

(define_predicate "vec_shift_operand"
 (and (match_code "const_vector")
      (match_test "GET_MODE_CLASS (mode) == MODE_VECTOR_INT"))
{
 unsigned elt = GET_MODE_NUNITS (mode) - 1;
 HOST_WIDE_INT ref = INTVAL (CONST_VECTOR_ELT (op, elt));
 while (--elt >= 0)
   {
     if (INTVAL (CONST_VECTOR_ELT (op, elt)) != ref)
       return 0;
   }
 return 1;
})

(define_expand "ashl<mode>3"
 [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
       (ashift:SSEMODE248
         (match_operand:SSEMODE248 1 "register_operand" "0")
         (match_operand:SSEMODE248 2 "vec_shift_operand" "xi")))]
 "TARGET_SSE2"
{
 operand[2] = CONST_VECTOR_ELT (operand[2], 0);
}

(define_insn "*sse_psll<mode>3"
 [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
       (ashift:SSEMODE248
         (match_operand:SSEMODE248 1 "register_operand" "0")
         (match_operand:SI 2 "nonmemory_operand" "xi")))]
 "TARGET_SSE2"
 "psll<ssevecsize>\t{%2, %0|%0, %2}"
 [(set_attr "type" "sseishft")
  (set_attr "mode" "TI")])

And similarly for ashr<mode>3 and lshr<mode>3.

This however will not fix "a << b" shifts, which right now should (my guess) ICE with something similar to PR22480.

By the way, it is time to remove the mmx_ prefix from the MMX insns!

Paolo


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]