aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-09-01 11:49:39 +0200
committerRichard Biener <rguenther@suse.de>2021-09-01 12:56:13 +0200
commit13a43a90aea368a25da50762eba4873bafb4e448 (patch)
treea6f2dbe2ca31cfcfb047ed7384745ed48eb519ff
parent153766ec8351d55cfe8bd6d69bdfc0c2cef71e56 (diff)
downloadgcc-13a43a90aea368a25da50762eba4873bafb4e448.zip
gcc-13a43a90aea368a25da50762eba4873bafb4e448.tar.gz
gcc-13a43a90aea368a25da50762eba4873bafb4e448.tar.bz2
tree-optimization/93491 - avoid PRE of trapping calls across exits
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. 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.
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr93491.c24
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr88087.c18
-rw-r--r--gcc/tree-ssa-pre.c33
-rw-r--r--gcc/tree-ssa-sccvn.c1
4 files changed, 60 insertions, 16 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr93491.c b/gcc/testsuite/gcc.dg/torture/pr93491.c
new file mode 100644
index 0000000..2cb4c0c
--- /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 d0061b6..c48dba5 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 ebe95cc..769aadb 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 bf87cee..2357bbd 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;