diff options
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 |