re PR middle-end/29272 (memcpy optimization causes wrong-code)

PR middle-end/29272
	* builtins.c (var_decl_component_p): New function.
	(fold_builtin_memset, fold_builtin_memory_op): Restrict
	single entry optimization to variables and components thereof.

	* gcc.c-torture/execute/20060930-2.c: New test.

From-SVN: r117599
This commit is contained in:
Jakub Jelinek 2006-10-10 11:46:59 +02:00 committed by Jakub Jelinek
parent be0436d7d9
commit 599a964a52
4 changed files with 63 additions and 0 deletions

View File

@ -1,3 +1,10 @@
2006-10-10 Jakub Jelinek <jakub@redhat.com>
PR middle-end/29272
* builtins.c (var_decl_component_p): New function.
(fold_builtin_memset, fold_builtin_memory_op): Restrict
single entry optimization to variables and components thereof.
2006-10-10 Richard Guenther <rguenther@suse.de>
PR rtl-optimization/29323

View File

@ -7893,6 +7893,17 @@ fold_builtin_exponent (tree fndecl, tree arglist,
return 0;
}
/* Return true if VAR is a VAR_DECL or a component thereof. */
static bool
var_decl_component_p (tree var)
{
tree inner = var;
while (handled_component_p (inner))
inner = TREE_OPERAND (inner, 0);
return SSA_VAR_P (inner);
}
/* Fold function call to builtin memset. Return
NULL_TREE if no simplification can be made. */
@ -7933,6 +7944,9 @@ fold_builtin_memset (tree arglist, tree type, bool ignore)
&& !POINTER_TYPE_P (TREE_TYPE (var)))
return 0;
if (! var_decl_component_p (var))
return 0;
length = tree_low_cst (len, 1);
if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
|| get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
@ -8044,6 +8058,9 @@ fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
&& !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar)))
return 0;
if (! var_decl_component_p (destvar))
return 0;
srcvar = src;
STRIP_NOPS (srcvar);
if (TREE_CODE (srcvar) != ADDR_EXPR)
@ -8058,6 +8075,9 @@ fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
&& !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar)))
return 0;
if (! var_decl_component_p (srcvar))
return 0;
length = tree_low_cst (len, 1);
if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar))) != length
|| get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT

View File

@ -1,3 +1,8 @@
2006-10-10 Jakub Jelinek <jakub@redhat.com>
PR middle-end/29272
* gcc.c-torture/execute/20060930-2.c: New test.
2006-10-09 Richard Henderson <rth@redhat.com>
Revert emutls patch.

View File

@ -0,0 +1,31 @@
/* PR middle-end/29272 */
extern void abort (void);
struct S { struct S *s; } s;
struct T { struct T *t; } t;
static inline void
foo (void *s)
{
struct T *p = s;
__builtin_memcpy (&p->t, &t.t, sizeof (t.t));
}
void *
__attribute__((noinline))
bar (void *p, struct S *q)
{
q->s = &s;
foo (p);
return q->s;
}
int
main (void)
{
t.t = &t;
if (bar (&s, &s) != (void *) &t)
abort ();
return 0;
}