mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-12 22:55:38 +08:00
re PR middle-end/41047 (gcc.target/mips/memcpy-1.c failing)
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
This commit is contained in:
parent
61a28f2135
commit
e5fdcd8cc5
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
24
gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-27.c
Normal file
24
gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-27.c
Normal file
@ -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" } } */
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user