From 8a18fcf4aa1d5c69d93d02ba3b4820ac03851cb2 Mon Sep 17 00:00:00 2001 From: Yuri Rumyantsev Date: Tue, 13 Oct 2015 13:08:31 +0000 Subject: [PATCH] PR tree-optimization/67909, 67947 gcc/ 2014-10-13 Yuri Rumyantsev PR tree-optimization/67909, 67947 * tree-ssa-loop-unswitch.c (find_loop_guard): Add check that GUARD_EDGE really skip the inner loop. gcc/testsuite/ 2014-10-13 Yuri Rumyantsev PR tree-optimization/67909, 67947 * gcc.dg/torture/pr67947.c: New test. From-SVN: r228760 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/torture/pr67947.c | 30 ++++++++++++++++++++++++++ gcc/tree-ssa-loop-unswitch.c | 11 +++++++++- 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr67947.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index caab5338ff6..68461a0a575 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-10-13 Yuri Rumyantsev + + PR tree-optimization/67909, 67947 + * tree-ssa-loop-unswitch.c (find_loop_guard): Add check that GUARD_EDGE + really skip the inner loop. + 2015-10-13 Jeff Law * tree-ssa-threadbackward.c (fsm_find_control_statement_thread_paths): diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index acf6df53b94..523b684e8ed 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-10-13 Yuri Rumyantsev + + PR tree-optimization/67909, 67947 + * gcc.dg/torture/pr67947.c: New test. + 2015-10-13 Jeff Law * gcc.dg/tree-ssa/ssa-thread-13.c: New test. diff --git a/gcc/testsuite/gcc.dg/torture/pr67947.c b/gcc/testsuite/gcc.dg/torture/pr67947.c new file mode 100644 index 00000000000..5664c48390a --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr67947.c @@ -0,0 +1,30 @@ +/* { dg-additional-options "-O3" } */ + +#include + +int a; +int c; +__attribute__((noinline, noclone)) void foo (int x) +{ + if (x == 0) + c++; +} + +int +main (int argc, char* argv[]) +{ + int j, k, b = 0; + if (argc == 0) + b = 1; + for (j = 0; j < 3; j++) + for (k = 0; k < 1; k++) + { + foo (0); + if (b) + for (k = -1; a;) + ; + } + if (c != 3) + abort (); + return 0; +} diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c index d6faa378ba8..2edc00031c6 100644 --- a/gcc/tree-ssa-loop-unswitch.c +++ b/gcc/tree-ssa-loop-unswitch.c @@ -471,7 +471,6 @@ find_loop_guard (struct loop *loop) { basic_block header = loop->header; edge guard_edge, te, fe; - /* bitmap processed, known_invariants;*/ basic_block *body = NULL; unsigned i; tree use; @@ -529,6 +528,16 @@ find_loop_guard (struct loop *loop) else return NULL; + /* Guard edge must skip inner loop. */ + if (!dominated_by_p (CDI_DOMINATORS, loop->inner->header, + guard_edge == fe ? te->dest : fe->dest)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Guard edge %d --> %d is not around the loop!\n", + guard_edge->src->index, guard_edge->dest->index); + return NULL; + } + if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Considering guard %d -> %d in loop %d\n", -- 2.30.2