https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88903

            Bug ID: 88903
           Summary: [8/9 Regression] wrong-code with SLP vectorized shift
           Product: gcc
           Version: 8.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org
  Target Milestone: ---

int x[1024];

void __attribute__((noinline)) foo()
{
  for (int i = 0; i < 512; ++i)
    {
      x[2*i] = x[2*i] << (i+1);
      x[2*i+1] = x[2*i+1] << (i+1);
    }
}

int main()
{
  for (int i = 0; i < 1024; ++i)
    x[i] = i;
  foo ();
  for (int i = 0; i < 1024; ++i)
    if (x[i] != i << (i/2+1))
      __builtin_abort ();
  return 0;
}

is vectorized using a scalar shift because

      /* In SLP, need to check whether the shift count is the same,
         in loops if it is a constant or invariant, it is always
         a scalar shift.  */
      if (slp_node)
        {
          vec<stmt_vec_info> stmts = SLP_TREE_SCALAR_STMTS (slp_node);
          stmt_vec_info slpstmt_info;

          FOR_EACH_VEC_ELT (stmts, k, slpstmt_info)
            {
              gassign *slpstmt = as_a <gassign *> (slpstmt_info->stmt);
              if (!operand_equal_p (gimple_assign_rhs2 (slpstmt), op1, 0))
                scalar_shift_arg = false;
            }
        }

only checks the scalar stmts covering half of the vector elements missing
that the other two will use a different shift value.

Reply via email to