diff options
author | Kewen Lin <linkw@gcc.gnu.org> | 2019-11-27 09:08:20 +0000 |
---|---|---|
committer | Kewen Lin <linkw@gcc.gnu.org> | 2019-11-27 09:08:20 +0000 |
commit | 1f9fae28095488a9accd1e7688116ed4d145b03f (patch) | |
tree | 48e7238b193350c87b3ef4042f14cf3f72c8d8c1 | |
parent | 66143cdfd1a3575ca5d92a6af788a4eb5c83f1b4 (diff) | |
download | gcc-1f9fae28095488a9accd1e7688116ed4d145b03f.zip gcc-1f9fae28095488a9accd1e7688116ed4d145b03f.tar.gz gcc-1f9fae28095488a9accd1e7688116ed4d145b03f.tar.bz2 |
[PATCH] Fix PR91790 by considering different first_stmt_info for realign
As PR91790 exposed, when we have one slp node whose first_stmt_info_for_drptr
is different from first_stmt_info, it's possible that the first_stmt DR isn't
initialized yet before stmt SLP_TREE_SCALAR_STMTS[0] of slp node. So we
shouldn't use first_stmt_info for vect_setup_realignment, instead we can use
the one based on first_stmt_info_for_drptr DR with additional adjustment by
bumping the distance from first_stmt DR.
gcc/ChangeLog
2019-11-27 Kewen Lin <linkw@gcc.gnu.org>
PR tree-optimization/91790
* gcc/tree-vect-stmts.c (vectorizable_load): Use the adjusted DR for
vect_setup_realignment when first_stmt_info is different from
first_stmt_info_for_drptr.
From-SVN: r278760
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 26 |
2 files changed, 28 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 78aa3ca..78b2f46 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-11-27 Kewen Lin <linkw@gcc.gnu.org> + + PR tree-optimization/91790 + * gcc/tree-vect-stmts.c (vectorizable_load): Use the adjusted + DR for vect_setup_realignment when first_stmt_info is different + from first_stmt_info_for_drptr. + 2019-11-27 Richard Biener <rguenther@suse.de> PR tree-optimization/92645 diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 6890837..f555fcc 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -9274,18 +9274,27 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, compute_in_loop = true; } + bool diff_first_stmt_info + = first_stmt_info_for_drptr && first_stmt_info != first_stmt_info_for_drptr; + if ((alignment_support_scheme == dr_explicit_realign_optimized || alignment_support_scheme == dr_explicit_realign) && !compute_in_loop) { - msq = vect_setup_realignment (first_stmt_info, gsi, &realignment_token, - alignment_support_scheme, NULL_TREE, - &at_loop); + /* If we have different first_stmt_info, we can't set up realignment + here, since we can't guarantee first_stmt_info DR has been + initialized yet, use first_stmt_info_for_drptr DR by bumping the + distance from first_stmt_info DR instead as below. */ + if (!diff_first_stmt_info) + msq = vect_setup_realignment (first_stmt_info, gsi, &realignment_token, + alignment_support_scheme, NULL_TREE, + &at_loop); if (alignment_support_scheme == dr_explicit_realign_optimized) { phi = as_a <gphi *> (SSA_NAME_DEF_STMT (msq)); byte_offset = size_binop (MINUS_EXPR, TYPE_SIZE_UNIT (vectype), size_one_node); + gcc_assert (!first_stmt_info_for_drptr); } } else @@ -9341,8 +9350,7 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr_info->dr)); dataref_offset = build_int_cst (ref_type, 0); } - else if (first_stmt_info_for_drptr - && first_stmt_info != first_stmt_info_for_drptr) + else if (diff_first_stmt_info) { dataref_ptr = vect_create_data_ref_ptr (first_stmt_info_for_drptr, @@ -9359,6 +9367,14 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, DR_INIT (ptrdr))); dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt_info, diff); + if (alignment_support_scheme == dr_explicit_realign) + { + msq = vect_setup_realignment (first_stmt_info_for_drptr, gsi, + &realignment_token, + alignment_support_scheme, + dataref_ptr, &at_loop); + gcc_assert (!compute_in_loop); + } } else if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)) vect_get_gather_scatter_ops (loop, stmt_info, &gs_info, |