From: Richard Guenther Date: Thu, 16 Apr 2009 12:44:46 +0000 (+0000) Subject: re PR tree-optimization/39698 (wrong types for vectorized reduction) X-Git-Tag: releases/gcc-4.5.0~6541 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=550918ca7dd62e7ac5e11cce696b73fa67227639;p=thirdparty%2Fgcc.git re PR tree-optimization/39698 (wrong types for vectorized reduction) 2009-04-16 Richard Guenther Ira Rosen PR tree-optimization/39698 * tree-vect-loop.c (get_initial_def_for_reduction): Use the type of the reduction variable. Only generate the def if it is needed. * omp-low.c (expand_omp_for_generic): When converting to a pointer make sure to first convert to an integer of the same precision. * tree-vect-loop-manip.c (vect_update_ivs_after_vectorizer): Retain the type of the evolution correctly in computing the new induction variable base. Co-Authored-By: Ira Rosen From-SVN: r146180 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f04bbcff5fc4..2068c9ce855e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2009-04-16 Richard Guenther + Ira Rosen + + PR tree-optimization/39698 + * tree-vect-loop.c (get_initial_def_for_reduction): Use the + type of the reduction variable. Only generate the def if + it is needed. + + * omp-low.c (expand_omp_for_generic): When converting to a pointer + make sure to first convert to an integer of the same precision. + * tree-vect-loop-manip.c (vect_update_ivs_after_vectorizer): Retain + the type of the evolution correctly in computing the new + induction variable base. + 2009-04-16 Richard Guenther PR middle-end/39625 diff --git a/gcc/omp-low.c b/gcc/omp-low.c index c28bbb0a1cae..0fa938acb2a0 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3812,21 +3812,25 @@ expand_omp_for_generic (struct omp_region *region, /* Iteration setup for sequential loop goes in L0_BB. */ gsi = gsi_start_bb (l0_bb); + t = istart0; if (bias) - t = fold_convert (type, fold_build2 (MINUS_EXPR, fd->iter_type, - istart0, bias)); - else - t = fold_convert (type, istart0); + t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias); + if (POINTER_TYPE_P (type)) + t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type), + 0), t); + t = fold_convert (type, t); t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, false, GSI_CONTINUE_LINKING); stmt = gimple_build_assign (fd->loop.v, t); gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING); + t = iend0; if (bias) - t = fold_convert (type, fold_build2 (MINUS_EXPR, fd->iter_type, - iend0, bias)); - else - t = fold_convert (type, iend0); + t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias); + if (POINTER_TYPE_P (type)) + t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type), + 0), t); + t = fold_convert (type, t); iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, false, GSI_CONTINUE_LINKING); if (fd->collapse > 1) diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index ae578f099fc6..56f9bba513d9 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -1593,7 +1593,8 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters, tree access_fn = NULL; tree evolution_part; tree init_expr; - tree step_expr; + tree step_expr, off; + tree type; tree var, ni, ni_name; gimple_stmt_iterator last_gsi; @@ -1623,6 +1624,11 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters, access_fn = analyze_scalar_evolution (loop, PHI_RESULT (phi)); gcc_assert (access_fn); + /* We can end up with an access_fn like + (short int) {(short unsigned int) i_49, +, 1}_1 + for further analysis we need to strip the outer cast but we + need to preserve the original type. */ + type = TREE_TYPE (access_fn); STRIP_NOPS (access_fn); evolution_part = unshare_expr (evolution_part_in_loop_num (access_fn, loop->num)); @@ -1635,22 +1641,19 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters, step_expr = evolution_part; init_expr = unshare_expr (initial_condition_in_loop_num (access_fn, loop->num)); + init_expr = fold_convert (type, init_expr); + off = fold_build2 (MULT_EXPR, TREE_TYPE (step_expr), + fold_convert (TREE_TYPE (step_expr), niters), + step_expr); if (POINTER_TYPE_P (TREE_TYPE (init_expr))) ni = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (init_expr), - init_expr, - fold_build2 (MULT_EXPR, sizetype, - fold_convert (sizetype, niters), - step_expr)); + init_expr, + fold_convert (sizetype, off)); else ni = fold_build2 (PLUS_EXPR, TREE_TYPE (init_expr), - fold_build2 (MULT_EXPR, TREE_TYPE (init_expr), - fold_convert (TREE_TYPE (init_expr), - niters), - step_expr), - init_expr); - - + init_expr, + fold_convert (TREE_TYPE (init_expr), off)); var = create_tmp_var (TREE_TYPE (init_expr), "tmp"); add_referenced_var (var); diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 9ae4403f38ca..d78fa99ff8b1 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -2267,33 +2267,33 @@ get_initial_def_for_reduction (gimple stmt, tree init_val, tree *adjustment_def) stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); - tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo); - int nunits = TYPE_VECTOR_SUBPARTS (vectype); - tree scalar_type = TREE_TYPE (vectype); + tree scalar_type = TREE_TYPE (init_val); + tree vectype = get_vectype_for_scalar_type (scalar_type); + int nunits; enum tree_code code = gimple_assign_rhs_code (stmt); - tree type = TREE_TYPE (init_val); - tree vecdef; tree def_for_init; tree init_def; tree t = NULL_TREE; int i; bool nested_in_vect_loop = false; - gcc_assert (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type)); + gcc_assert (vectype); + nunits = TYPE_VECTOR_SUBPARTS (vectype); + + gcc_assert (POINTER_TYPE_P (scalar_type) || INTEGRAL_TYPE_P (scalar_type) + || SCALAR_FLOAT_TYPE_P (scalar_type)); if (nested_in_vect_loop_p (loop, stmt)) nested_in_vect_loop = true; else gcc_assert (loop == (gimple_bb (stmt))->loop_father); - vecdef = vect_get_vec_def_for_operand (init_val, stmt, NULL); - switch (code) { case WIDEN_SUM_EXPR: case DOT_PROD_EXPR: case PLUS_EXPR: if (nested_in_vect_loop) - *adjustment_def = vecdef; + *adjustment_def = vect_get_vec_def_for_operand (init_val, stmt, NULL); else *adjustment_def = init_val; /* Create a vector of zeros for init_def. */ @@ -2310,7 +2310,7 @@ get_initial_def_for_reduction (gimple stmt, tree init_val, tree *adjustment_def) case MIN_EXPR: case MAX_EXPR: *adjustment_def = NULL_TREE; - init_def = vecdef; + init_def = vect_get_vec_def_for_operand (init_val, stmt, NULL); break; default: