diff options
author | Richard Biener <rguenther@suse.de> | 2015-01-15 08:41:08 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-01-15 08:41:08 +0000 |
commit | d679e96bbecf5a59940c99dfec883d9dd5ba81ea (patch) | |
tree | 5587549503935cc2c2538ef2bf5ef2be384b58d0 /gcc/tree-data-ref.c | |
parent | 5434dc0730795cf6a2ef8a9fe20e4dcc9cd077be (diff) | |
download | gcc-d679e96bbecf5a59940c99dfec883d9dd5ba81ea.zip gcc-d679e96bbecf5a59940c99dfec883d9dd5ba81ea.tar.gz gcc-d679e96bbecf5a59940c99dfec883d9dd5ba81ea.tar.bz2 |
re PR tree-optimization/64365 (Predictive commoning after loop vectorization produces incorrect code.)
2015-01-15 Richard Biener <rguenther@suse.de>
PR middle-end/64365
* tree-data-ref.c (dr_analyze_indices): Make sure that accesses
for MEM_REF access functions with the same base can never partially
overlap.
* gcc.dg/torture/pr64365.c: New testcase.
From-SVN: r219634
Diffstat (limited to 'gcc/tree-data-ref.c')
-rw-r--r-- | gcc/tree-data-ref.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 5c42e57..20a31bb 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -992,6 +992,22 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop) fold_convert (ssizetype, memoff)); memoff = build_int_cst (TREE_TYPE (memoff), 0); } + /* Adjust the offset so it is a multiple of the access type + size and thus we separate bases that can possibly be used + to produce partial overlaps (which the access_fn machinery + cannot handle). */ + wide_int rem; + if (TYPE_SIZE_UNIT (TREE_TYPE (ref)) + && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (ref))) == INTEGER_CST + && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (ref)))) + rem = wi::mod_trunc (off, TYPE_SIZE_UNIT (TREE_TYPE (ref)), SIGNED); + else + /* If we can't compute the remainder simply force the initial + condition to zero. */ + rem = off; + off = wide_int_to_tree (ssizetype, wi::sub (off, rem)); + memoff = wide_int_to_tree (TREE_TYPE (memoff), rem); + /* And finally replace the initial condition. */ access_fn = chrec_replace_initial_condition (access_fn, fold_convert (orig_type, off)); /* ??? This is still not a suitable base object for |