From eeeaf7199a10b61c188785e7a86cd3cdecba07c3 Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Mon, 21 Nov 2016 14:10:11 +0000 Subject: [PATCH] re PR tree-optimization/78413 (ICE in single_pred_edge, at basic-block.h:361) [gcc] 2016-11-21 Bill Schmidt PR tree-optimization/78413 * tree-if-conv.c (versionable_outer_loop_p): Require that both inner and outer loop latches have single predecessors. [gcc/testsuite] 2016-11-21 Bill Schmidt PR tree-optimization/78413 * gcc.dg/tree-ssa/pr78413.c: New test. From-SVN: r242661 --- gcc/ChangeLog | 6 +++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/tree-ssa/pr78413.c | 35 +++++++++++++++++++++++++ gcc/tree-if-conv.c | 6 ++++- 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr78413.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0e9376211c0..9fbecbd167a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-11-21 Bill Schmidt + + PR tree-optimization/78413 + * tree-if-conv.c (versionable_outer_loop_p): Require that both + inner and outer loop latches have single predecessors. + 2016-11-21 Georg-Johann Lay PR target/78093 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 924319e3ead..379c4f0490a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-11-21 Bill Schmidt + + PR tree-optimization/78413 + * gcc.dg/tree-ssa/pr78413.c: New test. + 2016-11-21 Thomas Preud'homme * gcc.target/arm/empty_fiq_handler.c: Skip if -mthumb is passed in and diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr78413.c b/gcc/testsuite/gcc.dg/tree-ssa/pr78413.c new file mode 100644 index 00000000000..049ecd79d4c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr78413.c @@ -0,0 +1,35 @@ +/* PR78413. These previously failed in tree if-conversion due to a loop + latch with multiple predecessors that the code did not anticipate. */ +/* { dg-do compile } */ +/* { dg-options "-O3 -ffast-math -fno-strict-aliasing" } */ + +extern long long int llrint(double x); +int a; +double b; +__attribute__((cold)) void decode_init() { + int c, d = 0; + for (; d < 12; d++) { + if (d) + b = 0; + c = 0; + for (; c < 6; c++) + a = b ? llrint(b) : 0; + } +} + +struct S { + _Bool bo; +}; +int a, bb, c, d; +void fn1() { + do + do + do { + struct S *e = (struct S *)1; + do + bb = a / (e->bo ? 2 : 1); + while (bb); + } while (0); + while (d); + while (c); +} diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 1235faf81b6..dc43d950cf1 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -2575,6 +2575,8 @@ version_loop_for_if_conversion (struct loop *loop) - The loop has a single exit. - The loop header has a single successor, which is the inner loop header. + - Each of the inner and outer loop latches have a single + predecessor. - The loop exit block has a single predecessor, which is the inner loop's exit block. */ @@ -2586,7 +2588,9 @@ versionable_outer_loop_p (struct loop *loop) || loop->inner->next || !single_exit (loop) || !single_succ_p (loop->header) - || single_succ (loop->header) != loop->inner->header) + || single_succ (loop->header) != loop->inner->header + || !single_pred_p (loop->latch) + || !single_pred_p (loop->inner->latch)) return false; basic_block outer_exit = single_pred (loop->latch); -- 2.30.2