diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 16e7d234a0d7e5922e9089084f4e78aab8682d3b..42d8bf4fe50c419613aeea2ba1a95567dc6aa402 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 eaea16df19ca281d5628ef77e95aa3eb313630be..7de2a7e183f2a9f0f3a5b8fe64a4cc1ae81ed2c5 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 fd1aa264cea479b81ab34817e336fe39104b6ce2..92575a3e06ae261d5f013b09c6403a1b8fa115d8 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 0000000000000000000000000000000000000000..c27963454713d4f52fbe88fe78aa69331ede6dea --- /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 f39d272964bbc96f3f970c4e8528e4b0307d7f28..b359d4c8d767fb0bdc2c17f75a0b4259cd4e36de 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 a40270335df7c7c8e3062f07a46b9a4cde3711a6..76e4e8b7f1b3c0ae0e18eae355cb424ac4b92828 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