diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/expr.c | 14 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 25 |
3 files changed, 34 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 22200e5..8e768f8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-08-18 Richard Guenther <rguenther@suse.de> + + * expr.c (get_inner_reference): Sign-extend the constant + twos-complement offset before doing arbitrary precision + arithmetic on it. + * tree-ssa-structalias.c (get_constraint_for_ptr_offset): Likewise. + (get_constraint_for_1): Pass the offset of a MEM_REF unchanged + to get_constraint_for_ptr_offset. + 2011-08-17 Kaz Kojima <kkojima@gcc.gnu.org> PR target/50068 @@ -6502,12 +6502,14 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, /* If OFFSET is constant, see if we can return the whole thing as a constant bit position. Make sure to handle overflow during this conversion. */ - if (host_integerp (offset, 0)) - { - double_int tem = double_int_lshift (tree_to_double_int (offset), - BITS_PER_UNIT == 8 - ? 3 : exact_log2 (BITS_PER_UNIT), - HOST_BITS_PER_DOUBLE_INT, true); + if (TREE_CODE (offset) == INTEGER_CST) + { + double_int tem = tree_to_double_int (offset); + tem = double_int_sext (tem, TYPE_PRECISION (sizetype)); + tem = double_int_lshift (tree_to_double_int (offset), + BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT), + HOST_BITS_PER_DOUBLE_INT, true); tem = double_int_add (tem, bit_offset); if (double_int_fits_in_shwi_p (tem)) { diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 79d4852..d69f14c 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -2876,7 +2876,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset, { struct constraint_expr c; unsigned int j, n; - HOST_WIDE_INT rhsunitoffset, rhsoffset; + HOST_WIDE_INT rhsoffset; /* If we do not do field-sensitive PTA adding offsets to pointers does not change the points-to solution. */ @@ -2891,15 +2891,24 @@ get_constraint_for_ptr_offset (tree ptr, tree offset, solution which includes all sub-fields of all pointed-to variables of ptr. */ if (offset == NULL_TREE - || !host_integerp (offset, 0)) + || TREE_CODE (offset) != INTEGER_CST) rhsoffset = UNKNOWN_OFFSET; else { - /* Make sure the bit-offset also fits. */ - rhsunitoffset = TREE_INT_CST_LOW (offset); - rhsoffset = rhsunitoffset * BITS_PER_UNIT; - if (rhsunitoffset != rhsoffset / BITS_PER_UNIT) + /* Sign-extend the offset. */ + double_int soffset + = double_int_sext (tree_to_double_int (offset), + TYPE_PRECISION (TREE_TYPE (offset))); + if (!double_int_fits_in_shwi_p (soffset)) rhsoffset = UNKNOWN_OFFSET; + else + { + /* Make sure the bit-offset also fits. */ + HOST_WIDE_INT rhsunitoffset = soffset.low; + rhsoffset = rhsunitoffset * BITS_PER_UNIT; + if (rhsunitoffset != rhsoffset / BITS_PER_UNIT) + rhsoffset = UNKNOWN_OFFSET; + } } get_constraint_for_rhs (ptr, results); @@ -3260,8 +3269,8 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p, { struct constraint_expr cs; varinfo_t vi, curr; - tree off = convert_to_ptrofftype (TREE_OPERAND (t, 1)); - get_constraint_for_ptr_offset (TREE_OPERAND (t, 0), off, results); + get_constraint_for_ptr_offset (TREE_OPERAND (t, 0), + TREE_OPERAND (t, 1), results); do_deref (results); /* If we are not taking the address then make sure to process |