From: jakub Date: Tue, 10 Oct 2006 09:46:59 +0000 (+0000) Subject: PR middle-end/29272 X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=e973ffcc24e08fbeee6be517d11796aeccdace9c;p=pf3gnuchains%2Fgcc-fork.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117599 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8c8d40501c..bc051ea9fd4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2006-10-10 Jakub Jelinek + + 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 PR rtl-optimization/29323 diff --git a/gcc/builtins.c b/gcc/builtins.c index 29974622ea1..46f97f9c879 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f60a8ee51c6..6cbfd6cecb0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-10-10 Jakub Jelinek + + PR middle-end/29272 + * gcc.c-torture/execute/20060930-2.c: New test. + 2006-10-09 Richard Henderson Revert emutls patch. diff --git a/gcc/testsuite/gcc.c-torture/execute/20060930-2.c b/gcc/testsuite/gcc.c-torture/execute/20060930-2.c new file mode 100644 index 00000000000..498f7811d1c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20060930-2.c @@ -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; +}