re PR middle-end/41047 (gcc.target/mips/memcpy-1.c failing)
authorRichard Guenther <rguenther@suse.de>
Thu, 13 Aug 2009 08:19:10 +0000 (08:19 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 13 Aug 2009 08:19:10 +0000 (08:19 +0000)
2009-08-13  Richard Guenther  <rguenther@suse.de>

PR middle-end/41047
* tree-ssa-ccp.c (ccp_fold): When folding pointer additions
use the constant pointer type.
* gimplify.c (canonicalize_addr_expr): Canonicalize independent
of CV qualifiers on the target pointer type.
* tree-ssa.c (useless_type_conversion_p): Move incomplete pointer
conversion check before restrict check.

* gcc.dg/tree-ssa/ssa-ccp-27.c: New testcase.

From-SVN: r150715

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-27.c [new file with mode: 0644]
gcc/tree-ssa-ccp.c
gcc/tree-ssa.c

index 16e7d23..42d8bf4 100644 (file)
@@ -1,3 +1,13 @@
+2009-08-13  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/41047
+       * tree-ssa-ccp.c (ccp_fold): When folding pointer additions
+       use the constant pointer type.
+       * gimplify.c (canonicalize_addr_expr): Canonicalize independent
+       of CV qualifiers on the target pointer type.
+       * tree-ssa.c (useless_type_conversion_p): Move incomplete pointer
+       conversion check before restrict check.
+
 2009-08-12  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        PR target/41029
index eaea16d..7de2a7e 100644 (file)
@@ -1763,7 +1763,8 @@ canonicalize_addr_expr (tree *expr_p)
      the expression pointer type.  */
   ddatype = TREE_TYPE (datype);
   pddatype = build_pointer_type (ddatype);
-  if (!useless_type_conversion_p (pddatype, ddatype))
+  if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
+                                 pddatype))
     return;
 
   /* The lower bound and element sizes must be constant.  */
@@ -1778,6 +1779,10 @@ canonicalize_addr_expr (tree *expr_p)
                    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
                    NULL_TREE, NULL_TREE);
   *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
+
+  /* We can have stripped a required restrict qualifier above.  */
+  if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
+    *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
 }
 
 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR.  Remove it and/or other conversions
index fd1aa26..92575a3 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-13  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/41047
+       * gcc.dg/tree-ssa/ssa-ccp-27.c: New testcase.
+
 2009-08-12  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/41011
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-27.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-27.c
new file mode 100644 (file)
index 0000000..c279634
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ccp1" } */
+
+#include <string.h>
+
+char c[10];
+
+void
+f1 ()
+{
+  const char *p = "123456";
+  memcpy (c, p, 6);
+}
+
+void
+f2 ()
+{
+  const char *p = "12345678";
+  p += 2;
+  memcpy (c, p, 6);
+}
+
+/* { dg-final { scan-tree-dump-times "memcpy\[^\n\]*123456" 2 "ccp1" } } */
+/* { dg-final { cleanup-tree-dump "ccp1" } } */
index f39d272..b359d4c 100644 (file)
@@ -1093,9 +1093,8 @@ ccp_fold (gimple stmt)
                  && TREE_CODE (op0) == ADDR_EXPR
                  && TREE_CODE (op1) == INTEGER_CST)
                {
-                 tree lhs = gimple_assign_lhs (stmt);
                  tree tem = maybe_fold_offset_to_address
-                   (loc, op0, op1, TREE_TYPE (lhs));
+                   (loc, op0, op1, TREE_TYPE (op0));
                  if (tem != NULL_TREE)
                    return tem;
                }
index a402703..76e4e8b 100644 (file)
@@ -874,6 +874,16 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
   if (POINTER_TYPE_P (inner_type)
       && POINTER_TYPE_P (outer_type))
     {
+      /* If the outer type is (void *) or a pointer to an incomplete
+        record type, then the conversion is not necessary.  */
+      if (VOID_TYPE_P (TREE_TYPE (outer_type))
+         || (AGGREGATE_TYPE_P (TREE_TYPE (outer_type))
+             && TREE_CODE (TREE_TYPE (outer_type)) != ARRAY_TYPE
+             && (TREE_CODE (TREE_TYPE (outer_type))
+                 == TREE_CODE (TREE_TYPE (inner_type)))
+             && !COMPLETE_TYPE_P (TREE_TYPE (outer_type))))
+       return true;
+
       /* Do not lose casts to restrict qualified pointers.  */
       if ((TYPE_RESTRICT (outer_type)
           != TYPE_RESTRICT (inner_type))
@@ -930,16 +940,6 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
   else if (POINTER_TYPE_P (inner_type)
           && POINTER_TYPE_P (outer_type))
     {
-      /* If the outer type is (void *) or a pointer to an incomplete
-        record type, then the conversion is not necessary.  */
-      if (VOID_TYPE_P (TREE_TYPE (outer_type))
-         || (AGGREGATE_TYPE_P (TREE_TYPE (outer_type))
-             && TREE_CODE (TREE_TYPE (outer_type)) != ARRAY_TYPE
-             && (TREE_CODE (TREE_TYPE (outer_type))
-                 == TREE_CODE (TREE_TYPE (inner_type)))
-             && !COMPLETE_TYPE_P (TREE_TYPE (outer_type))))
-       return true;
-
       /* Don't lose casts between pointers to volatile and non-volatile
         qualified types.  Doing so would result in changing the semantics
         of later accesses.  For function types the volatile qualifier