diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-09-25 10:12:49 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-09-25 10:12:49 +0200 |
commit | 356bbc4c20e346c2a513321b1bc8e9540876e6e0 (patch) | |
tree | d0ec2703a583c945535d901182f41b61cf38fdc2 /gcc/tree-vect-data-refs.c | |
parent | abdc17f81403fa566c44812777296c6d825c3e65 (diff) | |
download | gcc-356bbc4c20e346c2a513321b1bc8e9540876e6e0.zip gcc-356bbc4c20e346c2a513321b1bc8e9540876e6e0.tar.gz gcc-356bbc4c20e346c2a513321b1bc8e9540876e6e0.tar.bz2 |
re PR tree-optimization/63341 (Vectorization miscompilation with -mcpu=power7)
PR tree-optimization/63341
* tree-vectorizer.h (vect_create_data_ref_ptr,
vect_create_addr_base_for_vector_ref): Add another tree argument
defaulting to NULL_TREE.
* tree-vect-data-refs.c (vect_create_data_ref_ptr): Add byte_offset
argument, pass it down to vect_create_addr_base_for_vector_ref.
(vect_create_addr_base_for_vector_ref): Add byte_offset argument,
add that to base_offset too if non-NULL.
* tree-vect-stmts.c (vectorizable_load): Add byte_offset variable,
for dr_explicit_realign_optimized set it to vector byte size
- 1 instead of setting offset, pass byte_offset down to
vect_create_data_ref_ptr.
* gcc.dg/vect/pr63341-1.c: New test.
* gcc.dg/vect/pr63341-2.c: New test.
From-SVN: r215583
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 8785d10..b56348a 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -3860,6 +3860,9 @@ vect_get_new_vect_var (tree type, enum vect_var_kind var_kind, const char *name) is as follows: if LOOP=i_loop: &in (relative to i_loop) if LOOP=j_loop: &in+i*2B (relative to j_loop) + BYTE_OFFSET: Optional, defaulted to NULL. If supplied, it is added to the + initial address. Unlike OFFSET, which is number of elements to + be added, BYTE_OFFSET is measured in bytes. Output: 1. Return an SSA_NAME whose value is the address of the memory location of @@ -3873,7 +3876,8 @@ tree vect_create_addr_base_for_vector_ref (gimple stmt, gimple_seq *new_stmt_list, tree offset, - struct loop *loop) + struct loop *loop, + tree byte_offset) { stmt_vec_info stmt_info = vinfo_for_stmt (stmt); struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); @@ -3926,6 +3930,12 @@ vect_create_addr_base_for_vector_ref (gimple stmt, base_offset = fold_build2 (PLUS_EXPR, sizetype, base_offset, offset); } + if (byte_offset) + { + byte_offset = fold_convert (sizetype, byte_offset); + base_offset = fold_build2 (PLUS_EXPR, sizetype, + base_offset, byte_offset); + } /* base + base_offset */ if (loop_vinfo) @@ -3983,6 +3993,10 @@ vect_create_addr_base_for_vector_ref (gimple stmt, 5. BSI: location where the new stmts are to be placed if there is no loop 6. ONLY_INIT: indicate if ap is to be updated in the loop, or remain pointing to the initial address. + 7. BYTE_OFFSET (optional, defaults to NULL): a byte offset to be added + to the initial address accessed by the data-ref in STMT. This is + similar to OFFSET, but OFFSET is counted in elements, while BYTE_OFFSET + in bytes. Output: 1. Declare a new ptr to vector_type, and have it point to the base of the @@ -3996,6 +4010,8 @@ vect_create_addr_base_for_vector_ref (gimple stmt, initial_address = &a[init]; if OFFSET is supplied: initial_address = &a[init + OFFSET]; + if BYTE_OFFSET is supplied: + initial_address = &a[init] + BYTE_OFFSET; Return the initial_address in INITIAL_ADDRESS. @@ -4013,7 +4029,7 @@ tree vect_create_data_ref_ptr (gimple stmt, tree aggr_type, struct loop *at_loop, tree offset, tree *initial_address, gimple_stmt_iterator *gsi, gimple *ptr_incr, - bool only_init, bool *inv_p) + bool only_init, bool *inv_p, tree byte_offset) { const char *base_name; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); @@ -4156,10 +4172,10 @@ vect_create_data_ref_ptr (gimple stmt, tree aggr_type, struct loop *at_loop, /* (2) Calculate the initial address of the aggregate-pointer, and set the aggregate-pointer to point to it before the loop. */ - /* Create: (&(base[init_val+offset]) in the loop preheader. */ + /* Create: (&(base[init_val+offset]+byte_offset) in the loop preheader. */ new_temp = vect_create_addr_base_for_vector_ref (stmt, &new_stmt_list, - offset, loop); + offset, loop, byte_offset); if (new_stmt_list) { if (pe) |