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 :/