aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-03-14 10:01:20 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2025-03-14 12:06:54 +0100
commit6470b4d749a0b9896b985858ee6eae095cd8a37a (patch)
tree6425f06e52f2678f3f0ac86fe2a174acb517b644 /gcc
parentd1c5edc94b6d07ec29a93572f3b5086e88bf3b0e (diff)
downloadgcc-6470b4d749a0b9896b985858ee6eae095cd8a37a.zip
gcc-6470b4d749a0b9896b985858ee6eae095cd8a37a.tar.gz
gcc-6470b4d749a0b9896b985858ee6eae095cd8a37a.tar.bz2
tree-optimization/119274 - improve VN optimistic dominance query
The following improves how VN performs its dominance queries to determine availability, exploiting edges considered unreachable. The function already contains code to handle the leader block forking the CFG, but that looks like a situation that won't help the dominance query ever. The following adds handling of the more useful case where this block forwards to a CFG merge with the forwarder being the only executable entry. This helps optimizing the code so the spurious array diagnostic does no longer appear. PR tree-optimization/119274 * tree-ssa-sccvn.cc (dominated_by_p_w_unex): Handle the top block being the only executable forwarder to a CFG merge. * g++.dg/opt/pr119274.C: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/g++.dg/opt/pr119274.C20
-rw-r--r--gcc/tree-ssa-sccvn.cc28
2 files changed, 48 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/opt/pr119274.C b/gcc/testsuite/g++.dg/opt/pr119274.C
new file mode 100644
index 0000000..79b4061
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr119274.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -Wall" }
+
+#include <cstdlib>
+#include <vector>
+
+typedef std::vector<int> v1;
+
+static
+void drop_inplace(v1 & c, size_t len)
+{
+ if (len <= c.size())
+ c[len-1] = 0; /* { dg-bogus "outside array bounds" } */
+}
+
+void func()
+{
+ v1 vec1{1,2,3,4,5,6};
+ drop_inplace(vec1, 10);
+}
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 5a8c7c3..40c38fa 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -5169,6 +5169,34 @@ dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool allow_back)
}
}
}
+ /* Iterate to the single successor of bb2 with only a single executable
+ incoming edge. */
+ else if (EDGE_COUNT (bb2->succs) == 1
+ && EDGE_COUNT (single_succ (bb2)->preds) > 1)
+ {
+ edge prede = NULL;
+ FOR_EACH_EDGE (e, ei, single_succ (bb2)->preds)
+ if ((e->flags & EDGE_EXECUTABLE)
+ || (!allow_back && (e->flags & EDGE_DFS_BACK)))
+ {
+ if (prede)
+ {
+ prede = NULL;
+ break;
+ }
+ prede = e;
+ }
+ /* We might actually get to a query with BB2 not visited yet when
+ we're querying for a predicated value. */
+ if (prede && prede->src == bb2)
+ {
+ bb2 = prede->dest;
+
+ /* Re-do the dominance check with changed bb2. */
+ if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
+ return true;
+ }
+ }
/* We could now iterate updating bb1 / bb2. */
return false;