re PR tree-optimization/43784 (-Os -fkeep-inline-functions causes FAIL: gcc.c-torture/execute/builtins/pr22237.c execution)
2010-07-26 Richard Guenther <rguenther@suse.de> PR tree-optimization/43784 * tree-nrv.c (dest_safe_for_nrv_p): It's not safe to NRV if the destination is used by the call. * gcc.c-torture/execute/pr43784.c: New testcase. * g++.dg/torture/pr43784.C: Likewise. From-SVN: r162539
This commit is contained in:
parent
6a2ba1839d
commit
7f8ac3d7f9
5 changed files with 73 additions and 4 deletions
|
@ -1,3 +1,9 @@
|
|||
2010-07-26 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/43784
|
||||
* tree-nrv.c (dest_safe_for_nrv_p): It's not safe to NRV
|
||||
if the destination is used by the call.
|
||||
|
||||
2010-07-26 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/45073
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2010-07-26 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/43784
|
||||
* gcc.c-torture/execute/pr43784.c: New testcase.
|
||||
* g++.dg/torture/pr43784.C: Likewise.
|
||||
|
||||
2010-07-26 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/45056
|
||||
|
|
24
gcc/testsuite/g++.dg/torture/pr43784.C
Normal file
24
gcc/testsuite/g++.dg/torture/pr43784.C
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-options "-fno-tree-sra" } */
|
||||
|
||||
struct S {int x, y, makemelarge[5];};
|
||||
S __attribute__((noinline)) f (S &s) {
|
||||
S r;
|
||||
r.x = s.y;
|
||||
r.y = s.x;
|
||||
return r;
|
||||
}
|
||||
int __attribute__((noinline)) glob (int a, int b)
|
||||
{
|
||||
S local = { a, b };
|
||||
local = f (local);
|
||||
return local.y;
|
||||
}
|
||||
extern "C" void abort (void);
|
||||
int main (void)
|
||||
{
|
||||
if (glob (1, 3) != 1)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
||||
|
33
gcc/testsuite/gcc.c-torture/execute/pr43784.c
Normal file
33
gcc/testsuite/gcc.c-torture/execute/pr43784.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
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 struct s *p = &v.d.b;
|
||||
static struct s *q = &v.e.b;
|
||||
|
||||
static struct s __attribute__((noinline)) rp(void)
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
|
||||
static void qp(void)
|
||||
{
|
||||
*q = rp();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 256; i++)
|
||||
p->a[i] = i;
|
||||
qp();
|
||||
for (i = 0; i < 256; i++)
|
||||
if (q->a[i] != i)
|
||||
__builtin_abort();
|
||||
return 0;
|
||||
}
|
|
@ -296,7 +296,7 @@ struct gimple_opt_pass pass_nrv =
|
|||
optimization, where DEST is expected to be the LHS of a modify
|
||||
expression where the RHS is a function returning an aggregate.
|
||||
|
||||
DEST is available if it is not clobbered by the call. */
|
||||
DEST is available if it is not clobbered or used by the call. */
|
||||
|
||||
static bool
|
||||
dest_safe_for_nrv_p (gimple call)
|
||||
|
@ -310,7 +310,8 @@ dest_safe_for_nrv_p (gimple call)
|
|||
if (TREE_CODE (dest) == SSA_NAME)
|
||||
return true;
|
||||
|
||||
if (call_may_clobber_ref_p (call, dest))
|
||||
if (call_may_clobber_ref_p (call, dest)
|
||||
|| ref_maybe_used_by_stmt_p (call, dest))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -345,8 +346,7 @@ execute_return_slot_opt (void)
|
|||
&& gimple_call_lhs (stmt)
|
||||
&& !gimple_call_return_slot_opt_p (stmt)
|
||||
&& aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)),
|
||||
gimple_call_fndecl (stmt))
|
||||
)
|
||||
gimple_call_fndecl (stmt)))
|
||||
{
|
||||
/* Check if the location being assigned to is
|
||||
clobbered by the call. */
|
||||
|
|
Loading…
Add table
Reference in a new issue