aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-01-22 11:42:03 +0100
committerJakub Jelinek <jakub@redhat.com>2021-01-22 11:42:03 +0100
commite287a2a11d7958e5d9f7c6172e59cc83495e393a (patch)
treeffc177370b8b199ee6f381b0ac3f1b0009ea58d4 /gcc/tree-ssa-sccvn.c
parentfd61ca67f97acc5462d02676380af92329c37bb2 (diff)
downloadgcc-e287a2a11d7958e5d9f7c6172e59cc83495e393a.zip
gcc-e287a2a11d7958e5d9f7c6172e59cc83495e393a.tar.gz
gcc-e287a2a11d7958e5d9f7c6172e59cc83495e393a.tar.bz2
on ARRAY_REFs sign-extend offsets only from sizetype's precision [PR98255]
As discussed in the PR, the problem here is that the routines changed in this patch sign extend the difference of index and low_bound from the precision of the index, so e.g. when index is unsigned int and contains value -2U, we treat it as index -2 rather than 0x00000000fffffffeU on 64-bit arches. On the other hand, get_inner_reference which is used during expansion, does: if (! integer_zerop (low_bound)) index = fold_build2 (MINUS_EXPR, TREE_TYPE (index), index, low_bound); offset = size_binop (PLUS_EXPR, offset, size_binop (MULT_EXPR, fold_convert (sizetype, index), unit_size)); which effectively requires that either low_bound is constant 0 and then index in ARRAY_REFs can be arbitrary type which is then sign or zero extended to sizetype, or low_bound is something else and then index and low_bound must have compatible types and it is still converted afterwards to sizetype and from there then a few lines later: expr.c- if (poly_int_tree_p (offset)) expr.c- { expr.c: poly_offset_int tem = wi::sext (wi::to_poly_offset (offset), expr.c- TYPE_PRECISION (sizetype)); The following patch makes those routines match what get_inner_reference is doing. 2021-01-22 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/98255 * tree-dfa.c (get_ref_base_and_extent): For ARRAY_REFs, sign extend index - low_bound from sizetype's precision rather than index precision. (get_addr_base_and_unit_offset_1): Likewise. * tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Likewise. * gimple-fold.c (fold_const_aggregate_ref_1): Likewise. * gcc.dg/pr98255.c: New test.
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r--gcc/tree-ssa-sccvn.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 588f1b8..d45aee8 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1108,7 +1108,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
poly_offset_int woffset
= wi::sext (wi::to_poly_offset (op->op0)
- wi::to_poly_offset (op->op1),
- TYPE_PRECISION (TREE_TYPE (op->op0)));
+ TYPE_PRECISION (sizetype));
woffset *= wi::to_offset (op->op2) * vn_ref_op_align_unit (op);
woffset <<= LOG2_BITS_PER_UNIT;
offset += woffset;