https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95199
--- Comment #8 from Kaipeng Zhou <zhoukaipeng3 at huawei dot com> --- (In reply to bin cheng from comment #7) > (In reply to rguent...@suse.de from comment #6) > > On Thu, 21 May 2020, zhoukaipeng3 at huawei dot com wrote: > > > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95199 > > > > > > --- Comment #4 from Kaipeng Zhou <zhoukaipeng3 at huawei dot com> --- > > > Sorry for not expressing clearly. > > > > > > I have debugged the testcase you provided. Not eliminating them is not > > > caused > > > by IFN. The relevant code is in the "get_computation_aff_1" function. > > > > > > In IVOPTs the IV_STEPs must be checked by function "constant_multiple_of" > > > before using an IV variable to eliminate the other. But if the tree_code > > > of > > > input IV_STEP is SSA_NAME, the function will return false. In your > > > testcase, > > > the tree_code of IV_STEP is MULT_EXPR, so it return true. > > > > > > Gimple for my testcase: > > > <bb 12> [local count: 8589933]: > > > _83 = (sizetype) inc_y_22(D); > > > _84 = _83 * POLY_INT_CST [16, 16]; > > > _85 = (long unsigned int) inc_y_22(D); > > > _86 = _85 * 8; > > > _87 = (ssizetype) _86; > > > _88 = _87 /[ex] 8; > > > _89 = (long unsigned int) _88; > > > _90 = VEC_SERIES_EXPR <0, _89>; > > > vect_cst__95 = [vec_duplicate_expr] m_17(D); > > > _97 = (sizetype) inc_x_20(D); > > > _98 = _97 * POLY_INT_CST [16, 16]; > > > _99 = (long unsigned int) inc_x_20(D); > > > _100 = _99 * 8; > > > _101 = (ssizetype) _100; > > > _102 = _101 /[ex] 8; > > > _103 = (long unsigned int) _102; > > > _104 = VEC_SERIES_EXPR <0, _103>; > > > _109 = (sizetype) inc_x_20(D); > > > _110 = _109 * POLY_INT_CST [16, 16]; > > > _111 = (long unsigned int) inc_x_20(D); > > > > The issue is you have two copies of > > (sizetype) inc_x_20(D) * POLY_INT_CST [16, 16]; > > and IVOPTs does not perform CSE. vinfo->ivexpr_map is supposed to > > catch those "IV base and/or step expressions". So look where > > they are inserted and check the CSE map is used. Alternatively > > fixup hashing/comparing to handle POLY_INT_CST [16, 16] if that > > is the reason for the missed CSE. > > > Yes, it's because cse_and_gimplify_to_preheader is not called for > gathering/scattering. Should be easily fixed by following patch: > > diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c > index e7822c44951..ba9ee5c4996 100644 > --- a/gcc/tree-vect-stmts.c > +++ b/gcc/tree-vect-stmts.c > @@ -2961,6 +2961,7 @@ vect_get_strided_load_store_ops (stmt_vec_info > stmt_info, > tree bump = size_binop (MULT_EXPR, > fold_convert (sizetype, unshare_expr (DR_STEP > (dr))), > size_int (TYPE_VECTOR_SUBPARTS (vectype))); > + bump = cse_and_gimplify_to_preheader (loop_vinfo, bump); > *dataref_bump = force_gimple_operand (bump, &stmts, true, NULL_TREE); > if (stmts) > gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); I tested this patch and it worked fine on this testcase. Thanks a lot.