public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <rguenther@suse.de>
To: gcc-patches@gcc.gnu.org
Subject: [PATCH] tree-optimization/93491 - avoid PRE of trapping calls across exits
Date: Wed, 1 Sep 2021 12:56:04 +0200 (CEST)	[thread overview]
Message-ID: <579o3ss6-p36q-379n-5553-104r34r077o1@fhfr.qr> (raw)

This makes us avoid PREing calls that could trap across other
calls that might not return.  The PR88087 testcase has exactly
such case so I've refactored the testcase to contain a valid PRE.
I've also adjusted PRE to not consider pure calls possibly
not returning in line with what we do elsewhere.

Note we don't have a good idea whether a function always returns
normally or whether its body is known to never trap.  That's
something IPA could compute.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

2021-09-01  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/93491
	* tree-ssa-pre.c (compute_avail): Set BB_MAY_NOTRETURN
	after processing the stmt itself.  Do not consider
	pure functions possibly not returning.  Properly avoid
	adding possibly trapping calls to EXP_GEN when there's
	a preceeding possibly not returning call.
	* tree-ssa-sccvn.c (vn_reference_may_trap): Conservatively
	not handle calls.

	* gcc.dg/torture/pr93491.c: New testcase.
	* gcc.dg/tree-ssa/pr88087.c: Change to valid PRE opportunity.
---
 gcc/testsuite/gcc.dg/torture/pr93491.c  | 24 ++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr88087.c | 18 +++++++-------
 gcc/tree-ssa-pre.c                      | 33 +++++++++++++++++++------
 gcc/tree-ssa-sccvn.c                    |  1 +
 4 files changed, 60 insertions(+), 16 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr93491.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr93491.c b/gcc/testsuite/gcc.dg/torture/pr93491.c
new file mode 100644
index 00000000000..2cb4c0ca7af
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr93491.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+
+extern void exit (int);
+
+__attribute__((noipa))
+void f(int i)
+{
+  exit(i);
+}
+
+__attribute__((const,noipa))
+int g(int i)
+{
+  return 1 / i;
+}
+
+int main()
+{
+  while (1)
+    {
+      f(0);
+      f(g(0));
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c
index d0061b61aed..c48dba5bf21 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c
@@ -1,17 +1,17 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fno-code-hoisting -fdump-tree-pre-stats" } */
 
 int f();
 int d;
-void c()
+void c(int x)
 {
-  for (;;)
-    {
-      f();
-      int (*fp)() __attribute__((const)) = (void *)f;
-      d = fp();
-    }
+  int (*fp)() __attribute__((const)) = (void *)f;
+  if (x)
+    d = fp ();
+  int tem = fp ();
+  f();
+  d = tem;
 }
 
-/* We shouldn't ICE and hoist the const call of fp out of the loop.  */
+/* We shouldn't ICE and PRE the const call.  */
 /* { dg-final { scan-tree-dump "Eliminated: 1" "pre" } } */
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index ebe95cc6c73..769aadb2315 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3957,6 +3957,7 @@ compute_avail (function *fun)
 
       /* Now compute value numbers and populate value sets with all
 	 the expressions computed in BLOCK.  */
+      bool set_bb_may_notreturn = false;
       for (gimple_stmt_iterator gsi = gsi_start_bb (block); !gsi_end_p (gsi);
 	   gsi_next (&gsi))
 	{
@@ -3965,6 +3966,12 @@ compute_avail (function *fun)
 
 	  stmt = gsi_stmt (gsi);
 
+	  if (set_bb_may_notreturn)
+	    {
+	      BB_MAY_NOTRETURN (block) = 1;
+	      set_bb_may_notreturn = false;
+	    }
+
 	  /* Cache whether the basic-block has any non-visible side-effect
 	     or control flow.
 	     If this isn't a call or it is the last stmt in the
@@ -3976,10 +3983,12 @@ compute_avail (function *fun)
 		 that forbids hoisting possibly trapping expressions
 		 before it.  */
 	      int flags = gimple_call_flags (stmt);
-	      if (!(flags & ECF_CONST)
+	      if (!(flags & (ECF_CONST|ECF_PURE))
 		  || (flags & ECF_LOOPING_CONST_OR_PURE)
 		  || stmt_can_throw_external (fun, stmt))
-		BB_MAY_NOTRETURN (block) = 1;
+		/* Defer setting of BB_MAY_NOTRETURN to avoid it
+		   influencing the processing of the call itself.  */
+		set_bb_may_notreturn = true;
 	    }
 
 	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
@@ -4030,11 +4039,16 @@ compute_avail (function *fun)
 		/* If the value of the call is not invalidated in
 		   this block until it is computed, add the expression
 		   to EXP_GEN.  */
-		if (!gimple_vuse (stmt)
-		    || gimple_code
-		         (SSA_NAME_DEF_STMT (gimple_vuse (stmt))) == GIMPLE_PHI
-		    || gimple_bb (SSA_NAME_DEF_STMT
-				    (gimple_vuse (stmt))) != block)
+		if ((!gimple_vuse (stmt)
+		     || gimple_code
+			  (SSA_NAME_DEF_STMT (gimple_vuse (stmt))) == GIMPLE_PHI
+		     || gimple_bb (SSA_NAME_DEF_STMT
+				   (gimple_vuse (stmt))) != block)
+		    /* If the REFERENCE traps and there was a preceding
+		       point in the block that might not return avoid
+		       adding the reference to EXP_GEN.  */
+		    && (!BB_MAY_NOTRETURN (block)
+			|| !vn_reference_may_trap (ref)))
 		  {
 		    result = get_or_alloc_expr_for_reference
 			       (ref, gimple_location (stmt));
@@ -4220,6 +4234,11 @@ compute_avail (function *fun)
 	      break;
 	    }
 	}
+      if (set_bb_may_notreturn)
+	{
+	  BB_MAY_NOTRETURN (block) = 1;
+	  set_bb_may_notreturn = false;
+	}
 
       if (dump_file && (dump_flags & TDF_DETAILS))
 	{
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index bf87cee3857..2357bbdbf90 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -5851,6 +5851,7 @@ vn_reference_may_trap (vn_reference_t ref)
     case MODIFY_EXPR:
     case CALL_EXPR:
       /* We do not handle calls.  */
+      return true;
     case ADDR_EXPR:
       /* And toplevel address computations never trap.  */
       return false;
-- 
2.31.1

                 reply	other threads:[~2021-09-01 10:56 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=579o3ss6-p36q-379n-5553-104r34r077o1@fhfr.qr \
    --to=rguenther@suse.de \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).