https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110371
--- Comment #5 from Hongtao.liu <crazylht at gmail dot com> --- Reproduced with typedef struct dest { double m[3][3]; } dest; typedef struct src { int m[3][3]; } src; void foo (dest *a, src* s) { for (int i = 0; i != 3; i++) for (int j = 0; j != 3; j++) a->m[i][j] = s->m[i][j]; } for aarch64-linux-gnu. The problem is when there's more than 1 vop in vec_oprnds0, vec_dest will be overwrited to final vectype_out, but here it's expecting cvt_type. I'm testing below: Staged changes 1 file changed, 10 insertions(+), 4 deletions(-) gcc/tree-vect-stmts.cc | 14 ++++++++++---- modified gcc/tree-vect-stmts.cc @@ -5044,7 +5044,7 @@ vectorizable_conversion (vec_info *vinfo, gimple **vec_stmt, slp_tree slp_node, stmt_vector_for_cost *cost_vec) { - tree vec_dest; + tree vec_dest, cvt_op; tree scalar_dest; tree op0, op1 = NULL_TREE; loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo); @@ -5568,6 +5568,13 @@ vectorizable_conversion (vec_info *vinfo, case NONE: vect_get_vec_defs (vinfo, stmt_info, slp_node, ncopies, op0, &vec_oprnds0); + /* vec_dest is intermediate type operand when multi_step_cvt. */ + if (multi_step_cvt) + { + cvt_op = vec_dest; + vec_dest = vec_dsts[0]; + } + FOR_EACH_VEC_ELT (vec_oprnds0, i, vop0) { /* Arguments are ready, create the new vector stmt. */ @@ -5575,12 +5582,11 @@ vectorizable_conversion (vec_info *vinfo, if (multi_step_cvt) { gcc_assert (multi_step_cvt == 1); - new_stmt = vect_gimple_build (vec_dest, codecvt1, vop0); - new_temp = make_ssa_name (vec_dest, new_stmt); + new_stmt = vect_gimple_build (cvt_op, codecvt1, vop0); + new_temp = make_ssa_name (cvt_op, new_stmt); gimple_assign_set_lhs (new_stmt, new_temp); vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); vop0 = new_temp; - vec_dest = vec_dsts[0]; } new_stmt = vect_gimple_build (vec_dest, code1, vop0); new_temp = make_ssa_name (vec_dest, new_stmt); [back]