diff mbox series

Fix stmt_kills_ref_p wrt external throws

Message ID YrRussd86hOeSK0M@kam.mff.cuni.cz
State New
Headers show
Series Fix stmt_kills_ref_p wrt external throws | expand

Commit Message

Jan Hubicka June 23, 2022, 1:46 p.m. UTC
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

Richard Biener June 23, 2022, 1:52 p.m. UTC | #1
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)
>  	    {
>
diff mbox series

Patch

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.
 	 ???  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)
 	    {