This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Move POINTER_PLUS_EXPR folding to fold-const.c
- From: Richard Biener <rguenther at suse dot de>
- To: Marek Polacek <polacek at redhat dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jeff Law <law at redhat dot com>, "Joseph S. Myers" <joseph at codesourcery dot com>
- Date: Thu, 7 Aug 2014 09:45:13 +0200 (CEST)
- Subject: Re: [PATCH] Move POINTER_PLUS_EXPR folding to fold-const.c
- Authentication-results: sourceware.org; auth=none
- References: <20140806141909 dot GN24292 at redhat dot com>
On Wed, 6 Aug 2014, Marek Polacek wrote:
> As discussed in the other thread, I can't just remove folding from the
> C FE and implement it on GIMPLE level, because that regressed some of
> those not-really-kosher static initializers. Instead, fold-const.c
> has to be taught how to fold PTR0 - (PTR1 p+ A). (Now it sounds so
> obvious.) I added some test to that effect. And sorry - I'm clueless
> about the PSImode targets :(.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
Ok.
Thanks,
Richard.
> 2014-08-06 Marek Polacek <polacek@redhat.com>
>
> * fold-const.c (fold_binary_loc): Add folding of
> (PTR0 - (PTR1 p+ A) -> (PTR0 - PTR1) - A.
> c/
> * c-typeck.c (pointer_diff): Remove P - (P + CST) optimization.
> testsuite/
> * gcc.dg/fold-reassoc-3.c: New test.
>
> diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
> index 1b664bd..998e386 100644
> --- gcc/c/c-typeck.c
> +++ gcc/c/c-typeck.c
> @@ -3460,7 +3460,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
> addr_space_t as0 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0)));
> addr_space_t as1 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op1)));
> tree target_type = TREE_TYPE (TREE_TYPE (op0));
> - tree con0, con1, lit0, lit1;
> tree orig_op1 = op1;
>
> /* If the operands point into different address spaces, we need to
> @@ -3490,7 +3489,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
> else
> inttype = restype;
>
> -
> if (TREE_CODE (target_type) == VOID_TYPE)
> pedwarn (loc, OPT_Wpointer_arith,
> "pointer of type %<void *%> used in subtraction");
> @@ -3498,50 +3496,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
> pedwarn (loc, OPT_Wpointer_arith,
> "pointer to a function used in subtraction");
>
> - /* If the conversion to ptrdiff_type does anything like widening or
> - converting a partial to an integral mode, we get a convert_expression
> - that is in the way to do any simplifications.
> - (fold-const.c doesn't know that the extra bits won't be needed.
> - split_tree uses STRIP_SIGN_NOPS, which leaves conversions to a
> - different mode in place.)
> - So first try to find a common term here 'by hand'; we want to cover
> - at least the cases that occur in legal static initializers. */
> - if (CONVERT_EXPR_P (op0)
> - && (TYPE_PRECISION (TREE_TYPE (op0))
> - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))))
> - con0 = TREE_OPERAND (op0, 0);
> - else
> - con0 = op0;
> - if (CONVERT_EXPR_P (op1)
> - && (TYPE_PRECISION (TREE_TYPE (op1))
> - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))))
> - con1 = TREE_OPERAND (op1, 0);
> - else
> - con1 = op1;
> -
> - if (TREE_CODE (con0) == POINTER_PLUS_EXPR)
> - {
> - lit0 = TREE_OPERAND (con0, 1);
> - con0 = TREE_OPERAND (con0, 0);
> - }
> - else
> - lit0 = integer_zero_node;
> -
> - if (TREE_CODE (con1) == POINTER_PLUS_EXPR)
> - {
> - lit1 = TREE_OPERAND (con1, 1);
> - con1 = TREE_OPERAND (con1, 0);
> - }
> - else
> - lit1 = integer_zero_node;
> -
> - if (operand_equal_p (con0, con1, 0))
> - {
> - op0 = lit0;
> - op1 = lit1;
> - }
> -
> -
> /* First do the subtraction as integers;
> then drop through to build the divide operator.
> Do not do default conversions on the minus operator
> diff --git gcc/fold-const.c gcc/fold-const.c
> index 7180662..8d66957 100644
> --- gcc/fold-const.c
> +++ gcc/fold-const.c
> @@ -10831,6 +10831,19 @@ fold_binary_loc (location_t loc,
> if (tmp)
> return fold_build2_loc (loc, PLUS_EXPR, type, tmp, arg01);
> }
> + /* PTR0 - (PTR1 p+ A) -> (PTR0 - PTR1) - A, assuming PTR0 - PTR1
> + simplifies. */
> + else if (TREE_CODE (arg1) == POINTER_PLUS_EXPR)
> + {
> + tree arg10 = fold_convert_loc (loc, type,
> + TREE_OPERAND (arg1, 0));
> + tree arg11 = fold_convert_loc (loc, type,
> + TREE_OPERAND (arg1, 1));
> + tree tmp = fold_binary_loc (loc, MINUS_EXPR, type, arg0,
> + fold_convert_loc (loc, type, arg10));
> + if (tmp)
> + return fold_build2_loc (loc, MINUS_EXPR, type, tmp, arg11);
> + }
> }
> /* A - (-B) -> A + B */
> if (TREE_CODE (arg1) == NEGATE_EXPR)
> diff --git gcc/testsuite/gcc.dg/fold-reassoc-3.c gcc/testsuite/gcc.dg/fold-reassoc-3.c
> index e69de29..313fb98 100644
> --- gcc/testsuite/gcc.dg/fold-reassoc-3.c
> +++ gcc/testsuite/gcc.dg/fold-reassoc-3.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fdump-tree-original" } */
> +
> +int i;
> +int *p = &i;
> +static __PTRDIFF_TYPE__ d = p - (p + 1);
> +
> +void
> +foo (void)
> +{
> + int *q = &i;
> + static __PTRDIFF_TYPE__ e = q - (q + 1);
> +}
> +
> +/* { dg-final { scan-tree-dump-not " - " "original" } } */
> +/* { dg-final { scan-tree-dump-not " \\\+ " "original" } } */
> +/* { dg-final { cleanup-tree-dump "orginal" } } */
>
> Marek
>
>
--
Richard Biener <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer