This fell out of me looking into PR119835.  This doesn't resolve the underlying
issue, but instead of failing GIMPLE semantics verification just by chance in
the 'GIMPLE pass: nrv' context, it makes the issue observable generally.
(... thereby regressing a small number of offloading test cases where host vs.
offload compilers disagree on 'aggregate_value_p' for functions that return
aggregate types.)

This cross-references just the three places in the code that I ran into;
likely there are more?

No regressions for powerpc64le-unknown-linux-gnu, x86_64-pc-linux-gnu bootstrap
and 'make check' (without offloading configured).

        PR middle-end/119835
        gcc/
        * tree-cfg.cc (verify_gimple_return): Verify 'GIMPLE_RETURN' vs.
        'RESULT_DECL' if 'aggregate_value_p'.
        * gimplify.cc (gimplify_return_expr): Cross-reference it.
        * tree-nrv.cc (pass_nrv::execute): Likewise.
---
 gcc/gimplify.cc |  1 +
 gcc/tree-cfg.cc | 23 +++++++++++++++++++++++
 gcc/tree-nrv.cc |  1 +
 3 files changed, 25 insertions(+)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 4f385b1b779..ac296ab70bf 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -1903,6 +1903,7 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p)
     }
 
   /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
+     This is checked in 'tree-cfg.cc:verify_gimple_return'.
      Recall that aggregate_value_p is FALSE for any aggregate type that is
      returned in registers.  If we're returning values in registers, then
      we don't want to extend the lifetime of the RESULT_DECL, particularly
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index 6a95b82ff40..2fc99d54934 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -4892,6 +4892,29 @@ verify_gimple_return (greturn *stmt)
       return true;
     }
 
+  /* Verify 'gimplify.cc:gimplify_return_expr' property:
+     "If aggregate_value_p is true, then we can return the bare RESULT_DECL."
+  */
+  tree decl_result = DECL_RESULT (current_function_decl);
+  if (aggregate_value_p (decl_result, current_function_decl))
+    {
+      tree op_check;
+      if (TREE_CODE (op) == SSA_NAME)
+       op_check = SSA_NAME_VAR (op);
+      else
+       op_check = op;
+      if (op_check != decl_result)
+       {
+         error ("operand in return statement differs from %qs",
+                get_tree_code_name (TREE_CODE (decl_result)));
+         if (op != op_check)
+           debug_generic_stmt (op);
+         debug_generic_stmt (op_check);
+         debug_generic_stmt (decl_result);
+         return true;
+       }
+    }
+
   if ((TREE_CODE (op) == RESULT_DECL
        && DECL_BY_REFERENCE (op))
       || (TREE_CODE (op) == SSA_NAME
diff --git a/gcc/tree-nrv.cc b/gcc/tree-nrv.cc
index 180ce39de4c..6ac77567600 100644
--- a/gcc/tree-nrv.cc
+++ b/gcc/tree-nrv.cc
@@ -174,6 +174,7 @@ pass_nrv::execute (function *fun)
              /* In a function with an aggregate return value, the
                 gimplifier has changed all non-empty RETURN_EXPRs to
                 return the RESULT_DECL.  */
+             /* See also 'tree-cfg.cc:verify_gimple_return'.  */
              ret_val = gimple_return_retval (return_stmt);
              if (ret_val)
                gcc_assert (ret_val == result);
-- 
2.34.1

Reply via email to