+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
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. */
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
+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
--- /dev/null
+/* { 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" } } */
&& 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;
}
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))
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