aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/gimplify.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-27.c24
-rw-r--r--gcc/tree-ssa-ccp.c3
-rw-r--r--gcc/tree-ssa.c20
6 files changed, 56 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 16e7d23..42d8bf4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index eaea16d..7de2a7e 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fd1aa26..92575a3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..c279634
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-27.c
@@ -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" } } */
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index f39d272..b359d4c 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -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;
}
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index a402703..76e4e8b 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -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