re PR tree-optimization/22237 (struct copy inlining generates overlapping memcpy)

PR tree-opt/22237
        * tree-inline.c (declare_return_variable): Handle modify_dest not
        being a DECL.

From-SVN: r105057
This commit is contained in:
Richard Henderson 2005-10-06 13:46:53 -07:00 committed by Richard Henderson
parent 0c7c1604de
commit e2f9fe4298
4 changed files with 92 additions and 4 deletions

View File

@ -1,3 +1,9 @@
2005-10-06 Richard Henderson <rth@redhat.com>
PR tree-opt/22237
* tree-inline.c (declare_return_variable): Handle modify_dest not
being a DECL.
2005-10-06 Daniel Berlin <dberlin@dberlin.org>
Fix PR tree-optimization/22488

View File

@ -0,0 +1,27 @@
extern void abort (void);
void *
memcpy (void *dst, const void *src, __SIZE_TYPE__ n)
{
const char *srcp;
char *dstp;
srcp = src;
dstp = dst;
if (dst < src)
{
if (dst + n > src)
abort ();
}
else
{
if (src + n > dst)
abort ();
}
while (n-- != 0)
*dstp++ = *srcp++;
return dst;
}

View File

@ -0,0 +1,44 @@
extern void abort (void);
extern void exit (int);
struct s { unsigned char a[256]; };
union u { struct { struct s b; int c; } d; struct { int c; struct s b; } e; };
static union u v;
static union u v0;
static struct s *p = &v.d.b;
static struct s *q = &v.e.b;
static inline struct s rp (void) { return *p; }
static inline struct s rq (void) { return *q; }
static void pq (void) { *p = rq(); }
static void qp (void) { *q = rp(); }
static void
init (struct s *sp)
{
int i;
for (i = 0; i < 256; i++)
sp->a[i] = i;
}
static void
check (struct s *sp)
{
int i;
for (i = 0; i < 256; i++)
if (sp->a[i] != i)
abort ();
}
void
main_test (void)
{
v = v0;
init (p);
qp ();
check (q);
v = v0;
init (q);
pq ();
check (p);
exit (0);
}

View File

@ -1260,10 +1260,21 @@ declare_return_variable (inline_data *id, tree return_slot_addr,
/* If the callee cannot possibly modify MODIFY_DEST, then we can
reuse it as the result of the call directly. Don't do this if
it would promote MODIFY_DEST to addressable. */
else if (!TREE_STATIC (modify_dest)
&& !TREE_ADDRESSABLE (modify_dest)
&& !TREE_ADDRESSABLE (result))
use_it = true;
else if (TREE_ADDRESSABLE (result))
use_it = false;
else
{
tree base_m = get_base_address (modify_dest);
/* If the base isn't a decl, then it's a pointer, and we don't
know where that's going to go. */
if (!DECL_P (base_m))
use_it = false;
else if (is_global_var (base_m))
use_it = false;
else if (!TREE_ADDRESSABLE (base_m))
use_it = true;
}
if (use_it)
{