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.