Hi! On 2025-05-28T09:18:29+0200, Richard Biener <rguent...@suse.de> wrote: > On Tue, 27 May 2025, Thomas Schwinge wrote: >> "'GIMPLE_RETURN' vs. 'RESULT_DECL' if 'aggregate_value_p'" isn't actually >> a GIMPLE semantics invariant, thanks. I conclude that in case that this >> "invariant" is violated, that's not a problem for RTL expansion of >> 'GIMPLE_RETURN', which is then handled like all the other cases where >> "we are not returning the current function's RESULT_DECL". >> >> I'm not sure whether just disabling the 'assert' in >> 'gcc/tree-nrv.cc:pass_nrv::execute' is conceptually right (or may >> potentially drive that pass into an inconsistent state), and as we of >> course intend to eventually fix this issue properly (thanks for your >> ideas in PR119835!), so for now, I propose to simply >> "Disable 'pass_nrv' for offloading compilation [PR119835]", see attached. >> Any comments before I push that? > > I'm not sure you can disable this pass - it runs even at -O0
No, runs only for 'optimize > 0'. (I guess you were looking at 'pass_return_slot', living in the same file.) > so parts > of it might be required for correctness, since some types cannot be > copied. Maybe RTL expansion will apply NRV if that's the case, > irrespective of whether the flag is set, but maybe not. > > I think a more appropriate solution would be to simply change > the assert as follows > --- a/gcc/tree-nrv.cc > +++ b/gcc/tree-nrv.cc > @@ -171,12 +171,12 @@ pass_nrv::execute (function *fun) > > if (greturn *return_stmt = dyn_cast <greturn *> (stmt)) > { > - /* In a function with an aggregate return value, the > - gimplifier has changed all non-empty RETURN_EXPRs to > - return the RESULT_DECL. */ > + /* In a function with an aggregate return value, if > + there is a return that does not return RESULT_DECL > + we cannot perform NRV optimizations. */ > ret_val = gimple_return_retval (return_stmt); > - if (ret_val) > - gcc_assert (ret_val == result); > + if (ret_val && ret_val != result) > + return 0; > } > else if (gimple_has_lhs (stmt) Ah, right, in this scanning stage, no code transformations have been done yet, so we may still 'return 0;' (..., which then effectively also disables the pass). But, really also lose the check for non-offloading configurations, or do this defensive variant only '#ifdef ACCEL_COMPILER', as in the attached "Defuse 'RESULT_DECL' check in 'pass_nrv' for offloading compilation [PR119835]"? Grüße Thomas
>From 6f391a97d49072f3ff32ea397e3d70ad9103c196 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge <tschwi...@baylibre.com> Date: Tue, 27 May 2025 16:02:05 +0200 Subject: [PATCH] Defuse 'RESULT_DECL' check in 'pass_nrv' for offloading compilation [PR119835] ... to avoid running into ICEs per PR119835, until that's resolved properly. PR middle-end/119835 gcc/ * tree-nrv.cc (pass_nrv::gate) [ACCEL_COMPILER]: 'return false;'. libgomp/ * testsuite/libgomp.oacc-c-c++-common/abi-struct-1.c: '#pragma GCC optimize "-fno-inline"'. * testsuite/libgomp.c-c++-common/target-abi-struct-1.c: New. * testsuite/libgomp.c-c++-common/target-abi-struct-1-O0.c: Adjust. Co-authored-by: Richard Biener <rguent...@suse.de> --- gcc/tree-nrv.cc | 10 +++++++++- .../libgomp.c-c++-common/target-abi-struct-1-O0.c | 2 +- .../libgomp.c-c++-common/target-abi-struct-1.c | 1 + .../testsuite/libgomp.oacc-c-c++-common/abi-struct-1.c | 6 +++++- 4 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 libgomp/testsuite/libgomp.c-c++-common/target-abi-struct-1.c diff --git a/gcc/tree-nrv.cc b/gcc/tree-nrv.cc index 180ce39de4c..171d4c19f3e 100644 --- a/gcc/tree-nrv.cc +++ b/gcc/tree-nrv.cc @@ -176,7 +176,15 @@ pass_nrv::execute (function *fun) return the RESULT_DECL. */ ret_val = gimple_return_retval (return_stmt); if (ret_val) - gcc_assert (ret_val == result); + { +#ifdef ACCEL_COMPILER + /* PR119835 */ + if (ret_val != result) + return 0; +#else + gcc_assert (ret_val == result); +#endif + } } else if (gimple_has_lhs (stmt) && gimple_get_lhs (stmt) == result) diff --git a/libgomp/testsuite/libgomp.c-c++-common/target-abi-struct-1-O0.c b/libgomp/testsuite/libgomp.c-c++-common/target-abi-struct-1-O0.c index 35ec75d648d..9bf949a1f06 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/target-abi-struct-1-O0.c +++ b/libgomp/testsuite/libgomp.c-c++-common/target-abi-struct-1-O0.c @@ -1,3 +1,3 @@ /* { dg-additional-options -O0 } */ -#include "../libgomp.oacc-c-c++-common/abi-struct-1.c" +#include "target-abi-struct-1.c" diff --git a/libgomp/testsuite/libgomp.c-c++-common/target-abi-struct-1.c b/libgomp/testsuite/libgomp.c-c++-common/target-abi-struct-1.c new file mode 100644 index 00000000000..d9268af55cf --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/target-abi-struct-1.c @@ -0,0 +1 @@ +#include "../libgomp.oacc-c-c++-common/abi-struct-1.c" diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/abi-struct-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/abi-struct-1.c index 80786555fe2..4b541711f36 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/abi-struct-1.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/abi-struct-1.c @@ -1,6 +1,10 @@ /* Inspired by 'gcc.target/nvptx/abi-struct-arg.c', 'gcc.target/nvptx/abi-struct-ret.c'. */ -/* See also '../libgomp.c-c++-common/target-abi-struct-1-O0.c'. */ +/* See also '../libgomp.c-c++-common/target-abi-struct-1.c'. */ + +/* To exercise PR119835 (if optimizations enabled): disable inlining, so that + GIMPLE passes still see the functions that return aggregate types. */ +#pragma GCC optimize "-fno-inline" typedef struct {} empty; /* See 'gcc/doc/extend.texi', "Empty Structures". */ typedef struct {char a;} schar; -- 2.34.1