From 044331a86cdee0427e7b8552307c9e83f7088979 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 7 Aug 2014 08:12:04 +0000 Subject: [PATCH] fold-const.c (fold_binary_loc): Add folding of (PTR0 - (PTR1 p+ A) -> (PTR0 - PTR1) - A. * 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. From-SVN: r213700 --- gcc/ChangeLog | 5 +++ gcc/c/ChangeLog | 4 +++ gcc/c/c-typeck.c | 46 --------------------------- gcc/fold-const.c | 13 ++++++++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/fold-reassoc-3.c | 17 ++++++++++ 6 files changed, 43 insertions(+), 46 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/fold-reassoc-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 76c6d55f03c0..6ad4fe10112b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-08-07 Marek Polacek + + * fold-const.c (fold_binary_loc): Add folding of + (PTR0 - (PTR1 p+ A) -> (PTR0 - PTR1) - A. + 2013-08-07 Ilya Enkovich * config/elfos.h (ASM_DECLARE_OBJECT_NAME): Use decl size diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 35d958c18096..484a284b0fd9 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,7 @@ +2014-08-07 Marek Polacek + + * c-typeck.c (pointer_diff): Remove P - (P + CST) optimization. + 2014-08-02 Trevor Saunders * c-typeck.c: Use hash_map instead of pointer_map. diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 1b664bd0258b..998e3863a96f 100644 --- a/gcc/c/c-typeck.c +++ b/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 % 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 a/gcc/fold-const.c b/gcc/fold-const.c index 718066238efb..d44476972158 100644 --- a/gcc/fold-const.c +++ b/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 a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 248a3cc701ee..978bab8cbb53 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-08-07 Marek Polacek + + * gcc.dg/fold-reassoc-3.c: New test. + 2013-08-07 Ilya Enkovich * gcc.target/i386/struct-size.c: New. diff --git a/gcc/testsuite/gcc.dg/fold-reassoc-3.c b/gcc/testsuite/gcc.dg/fold-reassoc-3.c new file mode 100644 index 000000000000..313fb986e411 --- /dev/null +++ b/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" } } */ -- 2.47.3