diff options
Diffstat (limited to 'gcc/tree-vect-transform.c')
-rw-r--r-- | gcc/tree-vect-transform.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c index 161e82d..4775e2c 100644 --- a/gcc/tree-vect-transform.c +++ b/gcc/tree-vect-transform.c @@ -4786,13 +4786,17 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio) prolog_niters = min ( LOOP_NITERS , (VF/group_size - addr_mis/elem_size)&(VF/group_size-1) ) where group_size is the size of the interleaved group. -*/ + + The above formulas assume that VF == number of elements in the vector. This + may not hold when there are multiple-types in the loop. + In this case, for some data-references in the loop the VF does not represent + the number of elements that fit in the vector. Therefore, instead of VF we + use TYPE_VECTOR_SUBPARTS. */ static tree vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters) { struct data_reference *dr = LOOP_VINFO_UNALIGNED_DR (loop_vinfo); - int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); tree var, stmt; tree iters, iters_name; @@ -4805,6 +4809,7 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters) tree niters_type = TREE_TYPE (loop_niters); int group_size = 1; int element_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr)))); + int nelements = TYPE_VECTOR_SUBPARTS (vectype); if (DR_GROUP_FIRST_DR (stmt_info)) { @@ -4825,7 +4830,7 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters) if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "known alignment = %d.", byte_misalign); iters = build_int_cst (niters_type, - (vf - elem_misalign)&(vf/group_size-1)); + (nelements - elem_misalign)&(nelements/group_size-1)); } else { @@ -4837,9 +4842,9 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters) tree type = lang_hooks.types.type_for_size (tree_low_cst (size, 1), 1); tree vectype_size_minus_1 = build_int_cst (type, vectype_align - 1); tree elem_size_log = - build_int_cst (type, exact_log2 (vectype_align/vf)); - tree vf_minus_1 = build_int_cst (type, vf - 1); - tree vf_tree = build_int_cst (type, vf); + build_int_cst (type, exact_log2 (vectype_align/nelements)); + tree nelements_minus_1 = build_int_cst (type, nelements - 1); + tree nelements_tree = build_int_cst (type, nelements); tree byte_misalign; tree elem_misalign; @@ -4854,9 +4859,9 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters) elem_misalign = fold_build2 (RSHIFT_EXPR, type, byte_misalign, elem_size_log); - /* Create: (niters_type) (VF - elem_misalign)&(VF - 1) */ - iters = fold_build2 (MINUS_EXPR, type, vf_tree, elem_misalign); - iters = fold_build2 (BIT_AND_EXPR, type, iters, vf_minus_1); + /* Create: (niters_type) (nelements - elem_misalign)&(nelements - 1) */ + iters = fold_build2 (MINUS_EXPR, type, nelements_tree, elem_misalign); + iters = fold_build2 (BIT_AND_EXPR, type, iters, nelements_minus_1); iters = fold_convert (niters_type, iters); } |