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

Reply via email to