diff options
Diffstat (limited to 'gcc/tree-vect-loop-manip.c')
-rw-r--r-- | gcc/tree-vect-loop-manip.c | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index f78e4b4..5787d53 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -956,8 +956,7 @@ vect_gen_prolog_loop_niters (loop_vec_info loop_vinfo, gimple *dr_stmt = DR_STMT (dr); stmt_vec_info stmt_info = vinfo_for_stmt (dr_stmt); tree vectype = STMT_VINFO_VECTYPE (stmt_info); - int vectype_align = TYPE_ALIGN (vectype) / BITS_PER_UNIT; - int nelements = TYPE_VECTOR_SUBPARTS (vectype); + unsigned int target_align = DR_TARGET_ALIGNMENT (dr); if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) > 0) { @@ -978,32 +977,36 @@ vect_gen_prolog_loop_niters (loop_vec_info loop_vinfo, tree start_addr = vect_create_addr_base_for_vector_ref (dr_stmt, &stmts, offset); tree type = unsigned_type_for (TREE_TYPE (start_addr)); - tree vectype_align_minus_1 = build_int_cst (type, vectype_align - 1); - HOST_WIDE_INT elem_size = - int_cst_value (TYPE_SIZE_UNIT (TREE_TYPE (vectype))); + tree target_align_minus_1 = build_int_cst (type, target_align - 1); + HOST_WIDE_INT elem_size + = int_cst_value (TYPE_SIZE_UNIT (TREE_TYPE (vectype))); tree elem_size_log = build_int_cst (type, exact_log2 (elem_size)); - tree nelements_minus_1 = build_int_cst (type, nelements - 1); - tree nelements_tree = build_int_cst (type, nelements); - tree byte_misalign; - tree elem_misalign; - - /* Create: byte_misalign = addr & (vectype_align - 1) */ - byte_misalign = - fold_build2 (BIT_AND_EXPR, type, fold_convert (type, start_addr), - vectype_align_minus_1); - - /* Create: elem_misalign = byte_misalign / element_size */ - elem_misalign = - fold_build2 (RSHIFT_EXPR, type, byte_misalign, elem_size_log); - - /* Create: (niters_type) (nelements - elem_misalign)&(nelements - 1) */ + HOST_WIDE_INT align_in_elems = target_align / elem_size; + tree align_in_elems_minus_1 = build_int_cst (type, align_in_elems - 1); + tree align_in_elems_tree = build_int_cst (type, align_in_elems); + tree misalign_in_bytes; + tree misalign_in_elems; + + /* Create: misalign_in_bytes = addr & (target_align - 1). */ + misalign_in_bytes + = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, start_addr), + target_align_minus_1); + + /* Create: misalign_in_elems = misalign_in_bytes / element_size. */ + misalign_in_elems + = fold_build2 (RSHIFT_EXPR, type, misalign_in_bytes, elem_size_log); + + /* Create: (niters_type) ((align_in_elems - misalign_in_elems) + & (align_in_elems - 1)). */ if (negative) - iters = fold_build2 (MINUS_EXPR, type, elem_misalign, nelements_tree); + iters = fold_build2 (MINUS_EXPR, type, misalign_in_elems, + align_in_elems_tree); else - iters = fold_build2 (MINUS_EXPR, type, nelements_tree, elem_misalign); - iters = fold_build2 (BIT_AND_EXPR, type, iters, nelements_minus_1); + iters = fold_build2 (MINUS_EXPR, type, align_in_elems_tree, + misalign_in_elems); + iters = fold_build2 (BIT_AND_EXPR, type, iters, align_in_elems_minus_1); iters = fold_convert (niters_type, iters); - *bound = nelements - 1; + *bound = align_in_elems - 1; } if (dump_enabled_p ()) |