From efe040bf219da9f0aa2298c19909e392c784b3d3 Mon Sep 17 00:00:00 2001 From: Bin Cheng Date: Tue, 10 Oct 2017 09:02:13 +0000 Subject: [PATCH] tree-loop-distribution.c (generate_loops_for_partition): Remove inner loop's exit stmt by making it always exit the loop... * tree-loop-distribution.c (generate_loops_for_partition): Remove inner loop's exit stmt by making it always exit the loop, otherwise we would generate an infinite empty loop. gcc/testsuite * gcc.dg/tree-ssa/ldist-27.c: New test. From-SVN: r253580 --- gcc/ChangeLog | 6 ++++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/tree-ssa/ldist-27.c | 38 ++++++++++++++++++++++++ gcc/tree-loop-distribution.c | 16 ++++++++-- 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ldist-27.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6ce0d73dc47..01482824f71 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-10-10 Bin Cheng + + * tree-loop-distribution.c (generate_loops_for_partition): Remove + inner loop's exit stmt by making it always exit the loop, otherwise + we would generate an infinite empty loop. + 2017-10-10 Bin Cheng * tree-vect-loop-manip.c (slpeel_tree_duplicate_loop_to_edge_cfg): Skip diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index eb88b21c431..33a5cf55302 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-10-10 Bin Cheng + + * gcc.dg/tree-ssa/ldist-27.c: New test. + 2017-10-09 Michael Meissner * gcc.target/powerpc/amo1.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-27.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-27.c new file mode 100644 index 00000000000..3580c65f09b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-27.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -ftree-loop-distribute-patterns -fdump-tree-ldist-details" } */ + +#define M (300) +#define N (200) + +struct st +{ + double a[M]; + double b[M]; + double c[M][N]; +}; + +int __attribute__ ((noinline)) foo (struct st *s) +{ + int i, j; + for (i = 0; i != M;) + { + s->a[i] = 0.0; + s->b[i] = 1.0; + for (j = 0; 1; ++j) + { + if (j == N) goto L2; + s->c[i][j] = 0.0; + } +L2: + ++i; + } + return 0; +} + +int main (void) +{ + struct st s; + return foo (&s); +} + +/* { dg-final { scan-tree-dump "distributed: split to " "ldist" } } */ diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 3db3d6ec21e..999b32ef06c 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -830,6 +830,10 @@ generate_loops_for_partition (struct loop *loop, partition *partition, for (i = 0; i < loop->num_nodes; i++) { basic_block bb = bbs[i]; + edge inner_exit = NULL; + + if (loop != bb->loop_father) + inner_exit = single_exit (bb->loop_father); for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);) { @@ -848,11 +852,17 @@ generate_loops_for_partition (struct loop *loop, partition *partition, && !is_gimple_debug (stmt) && !bitmap_bit_p (partition->stmts, gimple_uid (stmt))) { - /* Choose an arbitrary path through the empty CFG part - that this unnecessary control stmt controls. */ + /* In distribution of loop nest, if bb is inner loop's exit_bb, + we choose its exit edge/path in order to avoid generating + infinite loop. For all other cases, we choose an arbitrary + path through the empty CFG part that this unnecessary + control stmt controls. */ if (gcond *cond_stmt = dyn_cast (stmt)) { - gimple_cond_make_false (cond_stmt); + if (inner_exit && inner_exit->flags & EDGE_TRUE_VALUE) + gimple_cond_make_true (cond_stmt); + else + gimple_cond_make_false (cond_stmt); update_stmt (stmt); } else if (gimple_code (stmt) == GIMPLE_SWITCH) -- 2.30.2