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

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Btw, it's this loop being vectorized:

      int i;
      for (i = 0; i < n_basic_blocks; i++)
        {
          basic_block b = BASIC_BLOCK (i);
          TBB d = di.dom[di.dfs_order[b->index]];

          /* The old code didn't modify array elements of nodes having only
             itself as dominator (d==0) or only ENTRY_BLOCK (resp. EXIT_BLOCK)
             (d==1).  */
          if (d > 1)
            idom[i] = di.dfs_to_bb[d]->index;
        }

di.dom[] and di.dfs_order[] are unsigned int, b->index is int, the blocks
are fetched from an array of pointers.  But the relevant difference is in
the vectorization of the masked (d > 1) gathers where di.dfs_to_bb is
basic_block *[].

struct basic_block { int index; };
void foo (int * __restrict idom, int n_basic_blocks, 
          unsigned int *indices, struct basic_block **dfs_to_bb)
{
  for (int i = 0; i < n_basic_blocks; ++i)
    {
      unsigned int d = indices[i];
      if (d > 1)
        idom[i] = dfs_to_bb[d]->index;
    }
}

does not vectorize because of alias issues, the .MASK_{LOAD,STORE} generated
by if-conversion do not carry along restrict info ...

Even making the store unconditional does not fix this particular issue.

Even simplified as

struct basic_block { int index; };
void foo (struct basic_block *__restrict *idom, int n_basic_blocks,
          unsigned int *indices, struct basic_block * __restrict *dfs_to_bb)
{
  for (int i = 0; i < n_basic_blocks; ++i)
    {
      unsigned int d = indices[i];
      struct basic_block *tem;
      if (d > 1)
        tem = dfs_to_bb[d];
      else
        tem = 0;
      idom[i] = tem;
    }
}

does not work :/

Reply via email to