* fold-const.c (fold_binary_loc): Add folding of
authormpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Aug 2014 08:12:04 +0000 (08:12 +0000)
committermpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Aug 2014 08:12:04 +0000 (08:12 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@213700 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/fold-reassoc-3.c [new file with mode: 0644]

index 76c6d55..6ad4fe1 100644 (file)
@@ -1,3 +1,8 @@
+2014-08-07  Marek Polacek  <polacek@redhat.com>
+
+       * fold-const.c (fold_binary_loc): Add folding of 
+       (PTR0 - (PTR1 p+ A) -> (PTR0 - PTR1) - A.
+
 2013-08-07  Ilya Enkovich  <ilya.enkovich@intel.com>
 
        * config/elfos.h (ASM_DECLARE_OBJECT_NAME): Use decl size
index 35d958c..484a284 100644 (file)
@@ -1,3 +1,7 @@
+2014-08-07  Marek Polacek  <polacek@redhat.com>
+
+       * c-typeck.c (pointer_diff): Remove P - (P + CST) optimization.
+
 2014-08-02  Trevor Saunders  <tsaunders@mozilla.com>
 
        * c-typeck.c: Use hash_map instead of pointer_map.
index 1b664bd..998e386 100644 (file)
@@ -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
index 7180662..d444769 100644 (file)
@@ -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)
index 248a3cc..978bab8 100644 (file)
@@ -1,3 +1,7 @@
+2014-08-07  Marek Polacek  <polacek@redhat.com>
+
+       * gcc.dg/fold-reassoc-3.c: New test.
+
 2013-08-07  Ilya Enkovich  <ilya.enkovich@intel.com>
 
        * 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 (file)
index 0000000..313fb98
--- /dev/null
@@ -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" } } */