auto_vec<chain_op_t> chain;
auto_vec<std::pair<tree_code, gimple *> > worklist;
gimple *op_stmt = NULL, *other_op_stmt = NULL;
- vect_slp_linearize_chain (vinfo, worklist, chain, (tree_code)code,
- scalar_stmts[0]->stmt, op_stmt, other_op_stmt,
- NULL);
-
- scalar_stmts.truncate (0);
- stmt_vec_info tail = NULL;
- for (auto el : chain)
+ if (is_a <gassign *> (scalar_stmts[0]->stmt)
+ /* We cannot linearize an operation that vect_slp_linearize_chain
+ would not put on its worklist. */
+ && gimple_assign_rhs_code (scalar_stmts[0]->stmt) == (tree_code)code)
{
- if (el.dt == vect_external_def
- || el.dt == vect_constant_def
- || el.code != (tree_code) code)
- {
- scalar_stmts.release ();
- return false;
- }
- stmt_vec_info stmt = vinfo->lookup_def (el.op);
- if (STMT_VINFO_REDUC_IDX (stmt) != -1
- || STMT_VINFO_REDUC_DEF (stmt))
+ vect_slp_linearize_chain (vinfo, worklist, chain, (tree_code)code,
+ scalar_stmts[0]->stmt, op_stmt,
+ other_op_stmt,
+ NULL);
+
+ scalar_stmts.truncate (0);
+ stmt_vec_info tail = NULL;
+ for (auto el : chain)
{
- gcc_assert (tail == NULL);
- tail = stmt;
- continue;
+ if (el.dt == vect_external_def
+ || el.dt == vect_constant_def
+ || el.code != (tree_code) code)
+ {
+ scalar_stmts.release ();
+ return false;
+ }
+ stmt_vec_info stmt = vinfo->lookup_def (el.op);
+ if (STMT_VINFO_REDUC_IDX (stmt) != -1
+ || STMT_VINFO_REDUC_DEF (stmt))
+ {
+ gcc_assert (tail == NULL);
+ tail = stmt;
+ continue;
+ }
+ scalar_stmts.safe_push (stmt);
}
- scalar_stmts.safe_push (stmt);
+ gcc_assert (tail);
}
- gcc_assert (tail);
/* When this linearization didn't produce a chain see if stripping
a wrapping sign conversion produces one. */
stmt, op_stmt, other_op_stmt, NULL);
scalar_stmts.truncate (0);
- tail = NULL;
+ stmt_vec_info tail = NULL;
for (auto el : chain)
{
if (el.dt == vect_external_def