Fix stmt_kills_ref_p wrt external throws
Commit Message
Hi,
this patch adds missing check to stmt_kills_ref_p for case that function
is terminated by EH before call return value kills the ref. In the PR
I tried to construct testcase but I don't know how to do that until I
annotate EH code with fnspec attributes which I will do in separate patch
and add a testcase.
Bootstrapped/regtested x86_64-linux, OK?
PR ipa/106057
* tree-ssa-alias.cc (stmt_kills_ref_p): Check for external throw.
Comments
On Thu, 23 Jun 2022, Jan Hubicka wrote:
> Hi,
> this patch adds missing check to stmt_kills_ref_p for case that function
> is terminated by EH before call return value kills the ref. In the PR
> I tried to construct testcase but I don't know how to do that until I
> annotate EH code with fnspec attributes which I will do in separate patch
> and add a testcase.
>
> Bootstrapped/regtested x86_64-linux, OK?
>
> PR ipa/106057
> * tree-ssa-alias.cc (stmt_kills_ref_p): Check for external throw.
> diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
> index b1e7a2d5afc..e427ee6744a 100644
> --- a/gcc/tree-ssa-alias.cc
> +++ b/gcc/tree-ssa-alias.cc
> @@ -87,10 +87,11 @@ along with GCC; see the file COPYING3. If not see
>
> This function tries to disambiguate two reference trees.
>
> - bool ptr_deref_may_alias_global_p (tree)
> + bool ptr_deref_may_alias_global_p (tree, bool)
>
> This function queries if dereferencing a pointer variable may
> - alias global memory.
> + alias global memory. If bool argument is true, global memory
> + is considered to also include function local memory that escaped.
>
> More low-level disambiguators are available and documented in
> this file. Low-level disambiguators dealing with points-to
> @@ -3333,11 +3334,18 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
> && TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME
> /* The assignment is not necessarily carried out if it can throw
> and we can catch it in the current function where we could inspect
> - the previous value.
> + the previous value. Similarly if the function can throw externally
> + and the ref does not diea on the function return.
die.
> ??? We only need to care about the RHS throwing. For aggregate
> assignments or similar calls and non-call exceptions the LHS
> - might throw as well. */
> - && !stmt_can_throw_internal (cfun, stmt))
> + might throw as well.
> + ??? We also should care about possible longjmp, but since we
> + do not understand that longjmp is not using global memory we will
> + not consider a kill here since the function call will be considered
> + as possibly using REF. */
> + && !stmt_can_throw_internal (cfun, stmt)
> + && (!stmt_can_throw_external (cfun, stmt)
> + || !ref_may_alias_global_p (ref, false)))
> {
> tree lhs = gimple_get_lhs (stmt);
> /* If LHS is literally a base of the access we are done. */
> @@ -3434,8 +3442,12 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
> && node->binds_to_current_def_p ()
> && (summary = get_modref_function_summary (node)) != NULL
> && summary->kills.length ()
> + /* Check that we can not trap while evaulating function
> + parameters. This check is overly conservative. */
> && (!cfun->can_throw_non_call_exceptions
> - || !stmt_can_throw_internal (cfun, stmt)))
> + || (!stmt_can_throw_internal (cfun, stmt)
> + && (!stmt_can_throw_external (cfun, stmt)
> + || !ref_may_alias_global_p (ref, stmt)))))
you wanted , false here instead of , stmt?
OK otherwise.
Thanks,
Richard.
> {
> for (auto kill : summary->kills)
> {
>
@@ -87,10 +87,11 @@ along with GCC; see the file COPYING3. If not see
This function tries to disambiguate two reference trees.
- bool ptr_deref_may_alias_global_p (tree)
+ bool ptr_deref_may_alias_global_p (tree, bool)
This function queries if dereferencing a pointer variable may
- alias global memory.
+ alias global memory. If bool argument is true, global memory
+ is considered to also include function local memory that escaped.
More low-level disambiguators are available and documented in
this file. Low-level disambiguators dealing with points-to
@@ -3333,11 +3334,18 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
&& TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME
/* The assignment is not necessarily carried out if it can throw
and we can catch it in the current function where we could inspect
- the previous value.
+ the previous value. Similarly if the function can throw externally
+ and the ref does not diea on the function return.
??? We only need to care about the RHS throwing. For aggregate
assignments or similar calls and non-call exceptions the LHS
- might throw as well. */
- && !stmt_can_throw_internal (cfun, stmt))
+ might throw as well.
+ ??? We also should care about possible longjmp, but since we
+ do not understand that longjmp is not using global memory we will
+ not consider a kill here since the function call will be considered
+ as possibly using REF. */
+ && !stmt_can_throw_internal (cfun, stmt)
+ && (!stmt_can_throw_external (cfun, stmt)
+ || !ref_may_alias_global_p (ref, false)))
{
tree lhs = gimple_get_lhs (stmt);
/* If LHS is literally a base of the access we are done. */
@@ -3434,8 +3442,12 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
&& node->binds_to_current_def_p ()
&& (summary = get_modref_function_summary (node)) != NULL
&& summary->kills.length ()
+ /* Check that we can not trap while evaulating function
+ parameters. This check is overly conservative. */
&& (!cfun->can_throw_non_call_exceptions
- || !stmt_can_throw_internal (cfun, stmt)))
+ || (!stmt_can_throw_internal (cfun, stmt)
+ && (!stmt_can_throw_external (cfun, stmt)
+ || !ref_may_alias_global_p (ref, stmt)))))
{
for (auto kill : summary->kills)
{