This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix handle_ptr_arith
- From: "Daniel Berlin" <dberlin at dberlin dot org>
- To: "Richard Guenther" <rguenther at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 3 Jun 2008 17:29:05 -0400
- Subject: Re: [PATCH] Fix handle_ptr_arith
- References: <Pine.LNX.4.64.0806031642230.26762@zhemvz.fhfr.qr>
Looks good to me
On Tue, Jun 3, 2008 at 10:44 AM, Richard Guenther <rguenther@suse.de> wrote:
>
> This fixes handle_ptr_arith to fall back to constraints from integer
> if a non-positive offset is added to a pointer.
>
> For the testcase
>
> int foo(int i)
> {
> int *p = &i + 1;
> int *q = p - 1;
> return *q;
> }
>
> we now correctly say p points to { } and q points to { ANYTHING }, while
> previously q pointed to { }.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu, ok?
>
> Thanks,
> Richard.
>
> 2008-06-03 Richard Guenther <rguenther@suse.de>
>
> * tree-ssa-structalias.c (handle_ptr_arith): Correctly handle
> negative or non-representable offsets.
>
> Index: gcc/tree-ssa-structalias.c
> ===================================================================
> *** gcc/tree-ssa-structalias.c (revision 136315)
> --- gcc/tree-ssa-structalias.c (working copy)
> *************** handle_ptr_arith (VEC (ce_s, heap) *lhsc
> *** 3531,3538 ****
> unsigned int i = 0;
> unsigned int j = 0;
> VEC (ce_s, heap) *temp = NULL;
> ! unsigned int rhsoffset = 0;
> ! bool unknown_addend = false;
>
> if (TREE_CODE (expr) != POINTER_PLUS_EXPR)
> return false;
> --- 3531,3537 ----
> unsigned int i = 0;
> unsigned int j = 0;
> VEC (ce_s, heap) *temp = NULL;
> ! unsigned HOST_WIDE_INT rhsunitoffset, rhsoffset;
>
> if (TREE_CODE (expr) != POINTER_PLUS_EXPR)
> return false;
> *************** handle_ptr_arith (VEC (ce_s, heap) *lhsc
> *** 3541,3553 ****
> op1 = TREE_OPERAND (expr, 1);
> gcc_assert (POINTER_TYPE_P (TREE_TYPE (op0)));
>
> ! get_constraint_for (op0, &temp);
>
> ! /* Handle non-constants by making constraints from integer. */
> ! if (TREE_CODE (op1) == INTEGER_CST)
> ! rhsoffset = TREE_INT_CST_LOW (op1) * BITS_PER_UNIT;
> ! else
> ! unknown_addend = true;
>
> for (i = 0; VEC_iterate (ce_s, lhsc, i, c); i++)
> for (j = 0; VEC_iterate (ce_s, temp, j, c2); j++)
> --- 3540,3557 ----
> op1 = TREE_OPERAND (expr, 1);
> gcc_assert (POINTER_TYPE_P (TREE_TYPE (op0)));
>
> ! /* If the offset is not a non-negative integer constant that fits
> ! in a HOST_WIDE_INT, we cannot handle it here. */
> ! if (!host_integerp (op1, 1))
> ! return false;
>
> ! /* Make sure the bit-offset also fits. */
> ! rhsunitoffset = TREE_INT_CST_LOW (op1);
> ! rhsoffset = rhsunitoffset * BITS_PER_UNIT;
> ! if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
> ! return false;
> !
> ! get_constraint_for (op0, &temp);
>
> for (i = 0; VEC_iterate (ce_s, lhsc, i, c); i++)
> for (j = 0; VEC_iterate (ce_s, temp, j, c2); j++)
> *************** handle_ptr_arith (VEC (ce_s, heap) *lhsc
> *** 3564,3593 ****
> c2->var = temp->id;
> c2->offset = 0;
> }
> - else if (unknown_addend)
> - {
> - /* Can't handle *a + integer where integer is unknown. */
> - if (c2->type != SCALAR)
> - {
> - struct constraint_expr intc;
> - intc.var = integer_id;
> - intc.offset = 0;
> - intc.type = SCALAR;
> - process_constraint (new_constraint (*c, intc));
> - }
> - else
> - {
> - /* We known it lives somewhere within c2->var. */
> - varinfo_t tmp = get_varinfo (c2->var);
> - for (; tmp; tmp = tmp->next)
> - {
> - struct constraint_expr tmpc = *c2;
> - c2->var = tmp->id;
> - c2->offset = 0;
> - process_constraint (new_constraint (*c, tmpc));
> - }
> - }
> - }
> else
> c2->offset = rhsoffset;
> process_constraint (new_constraint (*c, *c2));
> --- 3568,3573 ----
>