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:
parent
0c7c1604de
commit
e2f9fe4298
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue