Commit e2f9fe42 by Richard Henderson Committed by Richard Henderson

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
parent 0c7c1604
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> 2005-10-06 Daniel Berlin <dberlin@dberlin.org>
Fix PR tree-optimization/22488 Fix PR tree-optimization/22488
......
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;
}
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);
}
...@@ -1260,10 +1260,21 @@ declare_return_variable (inline_data *id, tree return_slot_addr, ...@@ -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 /* 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 reuse it as the result of the call directly. Don't do this if
it would promote MODIFY_DEST to addressable. */ it would promote MODIFY_DEST to addressable. */
else if (!TREE_STATIC (modify_dest) else if (TREE_ADDRESSABLE (result))
&& !TREE_ADDRESSABLE (modify_dest) use_it = false;
&& !TREE_ADDRESSABLE (result)) 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; use_it = true;
}
if (use_it) if (use_it)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment