re PR tree-optimization/19637 (Missed VRP and FRE opportunities in the presence of...
authorRichard Guenther <rguenther@suse.de>
Mon, 17 Mar 2008 14:34:21 +0000 (14:34 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 17 Mar 2008 14:34:21 +0000 (14:34 +0000)
2008-03-17  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/19637
* fold-const.c (fold_unary): Remove restrictions of removing
intermediate pointer-conversions (P2)(P1)P0.
* tree-ssa-ccp.c (maybe_fold_stmt_addition): Recover from
conversion to void pointer.
(get_maxval_strlen): Handle addresses of the form &(*p)[0].

* g++.dg/tree-ssa/pr19637.C: New testcase.

From-SVN: r133291

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr19637.C [new file with mode: 0644]
gcc/tree-ssa-ccp.c

index fa2ed097f625f90f867fc7bd6cdff8ef799a4682..28309279b79362d5a1464d070624404135cc60b1 100644 (file)
@@ -1,3 +1,12 @@
+2008-03-17  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/19637
+       * fold-const.c (fold_unary): Remove restrictions of removing
+       intermediate pointer-conversions (P2)(P1)P0.
+       * tree-ssa-ccp.c (maybe_fold_stmt_addition): Recover from
+       conversion to void pointer.
+       (get_maxval_strlen): Handle addresses of the form &(*p)[0].
+
 2008-03-16  James E. Wilson  <wilson@tuliptree.org>
 
        PR debug/31510
index 4dc4ad72e3cf3a9ace81943fbbc0cca87f8f74f5..3bfe52e0081f1eeee75e08cfe192b7222dacf8ab 100644 (file)
@@ -7784,9 +7784,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
             - the initial type is a pointer type and the precisions of the
               intermediate and final types differ, or
             - the final type is a pointer type and the precisions of the
-              initial and intermediate types differ.
-            - the initial type is a pointer to an array and the final type
-              not.  */
+              initial and intermediate types differ.  */
          if (! inside_float && ! inter_float && ! final_float
              && ! inside_vec && ! inter_vec && ! final_vec
              && (inter_prec >= inside_prec || inter_prec >= final_prec)
@@ -7798,10 +7796,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
              && ! (inside_ptr && inter_prec != final_prec)
              && ! (final_ptr && inside_prec != inter_prec)
              && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
-                   && TYPE_MODE (type) == TYPE_MODE (inter_type))
-             && ! (inside_ptr && final_ptr
-                   && TREE_CODE (TREE_TYPE (inside_type)) == ARRAY_TYPE
-                   && TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
+                   && TYPE_MODE (type) == TYPE_MODE (inter_type)))
            return fold_build1 (code, type, TREE_OPERAND (op0, 0));
        }
 
index 10ead70ab0134a4157921aefb16b4451553b9901..9242eca671cd7997edc08df8adba6d21e94388d0 100644 (file)
@@ -1,3 +1,8 @@
+2008-03-17  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/19637
+       * g++.dg/tree-ssa/pr19637.C: New testcase.
+
 2008-03-16  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/35470
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19637.C b/gcc/testsuite/g++.dg/tree-ssa/pr19637.C
new file mode 100644 (file)
index 0000000..2d1dcce
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dom1" } */
+
+#include <new>
+
+struct Foo {
+  Foo() { i[0] = 1; }
+  int i[2];
+};
+
+int foo_char(void)
+{
+  int i[2];
+  new (reinterpret_cast<char *>(i)) Foo();
+  return reinterpret_cast<Foo *>(i)->i[0];
+}
+
+int foo_void(void)
+{
+  int i[2];
+  new (reinterpret_cast<void *>(i)) Foo();
+  return reinterpret_cast<Foo *>(i)->i[0];
+}
+
+int foo_void_offset(void)
+{
+  int i[2];
+  new (reinterpret_cast<void *>(&i[0])) Foo();
+  return reinterpret_cast<Foo *>(&i[0])->i[0];
+}
+
+/* { dg-final { scan-tree-dump-times "return 1;" 3 "dom1" } } */
+/* { dg-final { cleanup-tree-dump "dom1" } } */
index f087a8d89486d5919fe4a6ef033847fa7d1b1ba1..7e519264f7a619dde9c8d800325293626be07015 100644 (file)
@@ -2105,6 +2105,12 @@ maybe_fold_stmt_addition (tree expr)
     }
 
   ptd_type = TREE_TYPE (ptr_type);
+  /* If we want a pointer to void, reconstruct the reference from the
+     array element type.  A pointer to that can be trivially converted
+     to void *.  This happens as we fold (void *)(ptr p+ off).  */
+  if (VOID_TYPE_P (ptd_type)
+      && TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE)
+    ptd_type = TREE_TYPE (TREE_TYPE (op0));
 
   /* At which point we can try some of the same things as for indirects.  */
   t = maybe_fold_offset_to_array_ref (op0, op1, ptd_type, true);
@@ -2292,6 +2298,17 @@ get_maxval_strlen (tree arg, tree *length, bitmap visited, int type)
       if (TREE_CODE (arg) == COND_EXPR)
         return get_maxval_strlen (COND_EXPR_THEN (arg), length, visited, type)
                && get_maxval_strlen (COND_EXPR_ELSE (arg), length, visited, type);
+      /* We can end up with &(*iftmp_1)[0] here as well, so handle it.  */
+      else if (TREE_CODE (arg) == ADDR_EXPR
+              && TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF
+              && integer_zerop (TREE_OPERAND (TREE_OPERAND (arg, 0), 1)))
+       {
+         tree aop0 = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
+         if (TREE_CODE (aop0) == INDIRECT_REF
+             && TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME)
+           return get_maxval_strlen (TREE_OPERAND (aop0, 0),
+                                     length, visited, type);
+       }
 
       if (type == 2)
        {