------- 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