aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-01-08 09:25:52 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2025-01-08 11:45:35 +0100
commiteca04660a2c9546c8ecefc5288395eb8a9fdc168 (patch)
treef7913fffdc97707e098ddd921e0e70d2f03a8484
parentec99905f7b39914ddb074c13ffbe05f0216784a1 (diff)
downloadgcc-eca04660a2c9546c8ecefc5288395eb8a9fdc168.zip
gcc-eca04660a2c9546c8ecefc5288395eb8a9fdc168.tar.gz
gcc-eca04660a2c9546c8ecefc5288395eb8a9fdc168.tar.bz2
tree-optimization/117979 - failed irreducible loop update from DCE
When CD-DCE creates forwarders to reduce false control dependences it fails to update the irreducible state of edge and the forwarder block in case the fowarder groups both normal (entry) and edges from an irreducible region (necessarily backedges). This is because when we split the first edge, if that's a normal edge, the forwarder and its edge to the original block will not be marked as part of the irreducible region but when we then redirect an edge from within the region it becomes so. The following fixes this up. Note I think creating a forwarder that includes backedges is likely not going to help, but at this stage I don't want to change the CFG going into DCE. For regular loops we'll have a single entry and a single backedge by means of loop init and will never create a forwarder - so this is solely happening for irreducible regions where it's harder to prove that such forwarder doesn't help. PR tree-optimization/117979 * tree-ssa-dce.cc (make_forwarders_with_degenerate_phis): Properly update the irreducible region state. * gcc.dg/torture/pr117979.c: New testcase.
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr117979.c21
-rw-r--r--gcc/tree-ssa-dce.cc10
2 files changed, 31 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr117979.c b/gcc/testsuite/gcc.dg/torture/pr117979.c
new file mode 100644
index 0000000..646cd70
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr117979.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+int a, b;
+void foo (void);
+int __attribute__((returns_twice)) bar (int);
+
+int __attribute__((const))
+baz (int f)
+{
+ if (f)
+ {
+ l:;
+ for (f = 0; f < 6; ++f)
+ if (bar (b))
+ goto l;
+ for (;; a--)
+ ;
+ }
+ foo ();
+ return 0;
+}
diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index adc7941..5b3037a 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -2032,14 +2032,24 @@ make_forwarders_with_degenerate_phis (function *fn)
free_dominance_info (fn, CDI_DOMINATORS);
basic_block forwarder = split_edge (args[start].first);
profile_count count = profile_count::zero ();
+ bool irr = false;
for (unsigned j = start + 1; j < i; ++j)
{
edge e = args[j].first;
+ if (e->flags & EDGE_IRREDUCIBLE_LOOP)
+ irr = true;
redirect_edge_and_branch_force (e, forwarder);
redirect_edge_var_map_clear (e);
count += e->count ();
}
forwarder->count = count;
+ if (irr)
+ {
+ forwarder->flags |= BB_IRREDUCIBLE_LOOP;
+ single_succ_edge (forwarder)->flags
+ |= EDGE_IRREDUCIBLE_LOOP;
+ }
+
if (vphi)
{
tree def = copy_ssa_name (vphi_args[0]);