aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTamar Christina <tamar.christina@arm.com>2024-01-10 12:51:54 +0000
committerTamar Christina <tamar.christina@arm.com>2024-01-10 12:52:25 +0000
commit9e7c77c7933b1bb0dd07214333e52a9a896fa349 (patch)
treed1a17dfcbb3c82155c2a1a8ccca8d3cd8fa17670 /gcc
parentd790565afa219a2b38cd74f419b3e56d9ed6f5a4 (diff)
downloadgcc-9e7c77c7933b1bb0dd07214333e52a9a896fa349.zip
gcc-9e7c77c7933b1bb0dd07214333e52a9a896fa349.tar.gz
gcc-9e7c77c7933b1bb0dd07214333e52a9a896fa349.tar.bz2
middle-end: Fix dominators updates when peeling with multiple exits [PR113144]
When we peel at_exit we are moving the new loop at the exit of the previous loop. This means that the blocks outside the loop dat the previous loop used to dominate are no longer being dominated by it. The new dominators however are hard to predict since if the loop has multiple exits and all the exits are an "early" one then we always execute the scalar loop. In this case the scalar loop can completely dominate the new loop. If we later have skip_vector then there's an additional skip edge added that might change the dominators. The previous patch would force an update of all blocks reachable from the new exits. This one updates *only* blocks that we know the scalar exits dominated. For the examples this reduces the blocks to update from 18 to 3. gcc/ChangeLog: PR tree-optimization/113144 PR tree-optimization/113145 * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg): Update all BB that the original exits dominated. gcc/testsuite/ChangeLog: PR tree-optimization/113144 PR tree-optimization/113145 * gcc.dg/vect/vect-early-break_94-pr113144.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c41
-rw-r--r--gcc/tree-vect-loop-manip.cc13
2 files changed, 45 insertions, 9 deletions
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c
new file mode 100644
index 0000000..903fe7b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+long tar_atol256_max, tar_atol256_size, tar_atosl_min;
+char tar_atol256_s;
+void __errno_location();
+
+
+inline static long tar_atol256(long min) {
+ char c;
+ int sign;
+ c = tar_atol256_s;
+ sign = c;
+ while (tar_atol256_size) {
+ if (c != sign)
+ return sign ? min : tar_atol256_max;
+ c = tar_atol256_size--;
+ }
+ if ((c & 128) != (sign & 128))
+ return sign ? min : tar_atol256_max;
+ return 0;
+}
+
+inline static long tar_atol(long min) {
+ return tar_atol256(min);
+}
+
+long tar_atosl() {
+ long n = tar_atol(-1);
+ if (tar_atosl_min) {
+ __errno_location();
+ return 0;
+ }
+ if (n > 0)
+ return 0;
+ return n;
+}
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index f0ea7fc..8aa7575 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -1716,8 +1716,6 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
/* Now link the alternative exits. */
if (multiple_exits_p)
{
- set_immediate_dominator (CDI_DOMINATORS, new_preheader,
- main_loop_exit_block);
for (auto gsi_from = gsi_start_phis (loop->header),
gsi_to = gsi_start_phis (new_preheader);
!gsi_end_p (gsi_from) && !gsi_end_p (gsi_to);
@@ -1755,13 +1753,10 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
if (multiple_exits_p)
{
update_loop = new_loop;
- for (edge e : get_loop_exit_edges (loop))
- doms.safe_push (e->dest);
- doms.safe_push (exit_dest);
-
- /* Likely a fall-through edge, so update if needed. */
- if (single_succ_p (exit_dest))
- doms.safe_push (single_succ (exit_dest));
+ doms = get_all_dominated_blocks (CDI_DOMINATORS, loop->header);
+ for (unsigned i = 0; i < doms.length (); ++i)
+ if (flow_bb_inside_loop_p (loop, doms[i]))
+ doms.unordered_remove (i);
}
}
else /* Add the copy at entry. */