------- Comment #6 from jakub at gcc dot gnu dot org 2007-06-13 15:22 -------
I see that PR25505 caused a bunch of code generation regressions.
On i?86, with -O2 -m32:
_Complex double foo (_Complex double x)
{
return __builtin_cexp (x);
}
generated code got much worse, similarly:
elemental function specific__exp_c8 (parm)
complex (kind=8), intent (in) :: parm
complex (kind=8) :: specific__exp_c8
specific__exp_c8 = exp (parm)
end function
In the above 2 cases, dest_safe_for_nrv_p is called on an SSA_NAME. At least
in
these cases it should be safe to use SSA_NAME_VAR, shouldn't it?
A different testcase that regressed is:
struct P
{
long long l;
int a;
unsigned int b;
P(long long x) : l(x) {}
};
P foo (P);
P bar (P);
P foo (P x)
{
P y = P (-1LL);
y = bar (x);
return y;
}
Here dest_safe_for_nrv_p is passed a RESULT_DECL and is again something
that ought to be optimized out, but is not any longer.
static bool
dest_safe_for_nrv_p (tree dest, location_t *loc)
{
subvar_t subvar;
while (handled_component_p (dest))
dest = TREE_OPERAND (dest, 0);
if (! SSA_VAR_P (dest))
return false;
if (TREE_CODE (dest) == SSA_NAME)
dest = SSA_NAME_VAR (dest);
if (is_call_clobbered (dest))
return false;
for (subvar = get_subvars_for_var (dest); subvar; subvar = subvar->next)
if (is_call_clobbered (subvar->var))
return false;
return true;
}
handles all of these (i.e. doesn't regress on any of them). I have verified
that
it e.g. refuses to NRV optimize:
struct P
{
long long l;
int a;
unsigned int b;
P(long long x) : l(x) {}
};
P foo (P);
P bar (P);
void baz (P *);
P foo (P x)
{
P y = P (-1LL);
baz (&y);
y = bar (x);
return y;
}
because the RESULT_DECL escapes.
It regresses on the initial testcase from this bugreport, so it would mean
writing a different bugfix (most probably in calls.c, check that the target
doesn't overlap with the arguments being pushed), but it might very well be
worth it.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32285