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