aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-loop-jam.cc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2022-02-15 12:27:14 +0100
committerRichard Biener <rguenther@suse.de>2022-02-15 13:22:15 +0100
commitd03a67dc69251dc86c0772a432380a6e9bcb8617 (patch)
tree751d42d3e61a78d5aa8d25fc1d77a05cc9c78ab3 /gcc/gimple-loop-jam.cc
parent3939c1b11279dc950d2f160eb940dd791f7b40f1 (diff)
downloadgcc-d03a67dc69251dc86c0772a432380a6e9bcb8617.zip
gcc-d03a67dc69251dc86c0772a432380a6e9bcb8617.tar.gz
gcc-d03a67dc69251dc86c0772a432380a6e9bcb8617.tar.bz2
tree-optimization/104543 - fix unroll-and-jam precondition
We have to make sure that outer loop exits come after the inner loop since we otherwise will put it into the fused loop body. 2022-02-15 Richard Biener <rguenther@suse.de> PR tree-optimization/104543 * gimple-loop-jam.cc (unroll_jam_possible_p): Check outer loop exits come after the inner loop. * gcc.dg/torture/pr104543.c: New testcase.
Diffstat (limited to 'gcc/gimple-loop-jam.cc')
-rw-r--r--gcc/gimple-loop-jam.cc10
1 files changed, 8 insertions, 2 deletions
diff --git a/gcc/gimple-loop-jam.cc b/gcc/gimple-loop-jam.cc
index d9a7772..e33dd90 100644
--- a/gcc/gimple-loop-jam.cc
+++ b/gcc/gimple-loop-jam.cc
@@ -198,7 +198,8 @@ unroll_jam_possible_p (class loop *outer, class loop *loop)
if (!empty_block_p (loop->latch))
return false;
- if (!single_exit (loop))
+ edge exit;
+ if (!(exit = single_exit (loop)))
return false;
/* We need a perfect nest. Quick check for adjacent inner loops. */
@@ -259,7 +260,12 @@ unroll_jam_possible_p (class loop *outer, class loop *loop)
n = get_loop_body_with_size (outer, bbs, n_basic_blocks_for_fn (cfun));
for (i = 0; i < n; i++)
- if (bbs[i]->loop_father == outer && bb_prevents_fusion_p (bbs[i]))
+ if (bbs[i]->loop_father == outer
+ && (bb_prevents_fusion_p (bbs[i])
+ /* Outer loop exits must come after the inner loop, otherwise
+ we'll put the outer loop exit into the fused inner loop. */
+ || (loop_exits_from_bb_p (outer, bbs[i])
+ && !dominated_by_p (CDI_DOMINATORS, bbs[i], exit->src))))
break;
free (bbs);
if (i != n)