From 5a2a87e1e2452eddae38e0ae1af4239f92d8c281 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 8 Jan 2018 11:20:21 -0700 Subject: [PATCH] re PR rtl-optimization/81308 (ICE in calc_dfs_tree, at dominance.c:458) PR rtl-optimizatin/81308 * tree-switch-conversion.c (cfg_altered): New file scoped static. (process_switch): If group_case_labels makes a change, then set cfg_altered. (pass_convert_switch::execute): If a switch is converted, then set cfg_altered. Return TODO_cfg_cleanup if cfg_altered is true. PR rtl-optimizatin/81308 * g++.dg/pr81308-1.C: New test. * g++.dg/pr81308-2.C: New test. From-SVN: r256349 --- gcc/ChangeLog | 7 ++++ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/g++.dg/pr81308-1.C | 67 ++++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/pr81308-2.C | 38 ++++++++++++++++++ gcc/tree-switch-conversion.c | 10 ++++- 5 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/pr81308-1.C create mode 100644 gcc/testsuite/g++.dg/pr81308-2.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 762aea53b17..7599c556a25 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2017-01-08 Jeff Law + PR rtl-optimizatin/81308 + * tree-switch-conversion.c (cfg_altered): New file scoped static. + (process_switch): If group_case_labels makes a change, then set + cfg_altered. + (pass_convert_switch::execute): If a switch is converted, then + set cfg_altered. Return TODO_cfg_cleanup if cfg_altered is true. + PR rtl-optimization/81308 * recog.c (split_all_insns): Conditionally cleanup the CFG after splitting insns. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5c138730693..33f8bddd983 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-01-08 Jeff Law + + PR rtl-optimizatin/81308 + * g++.dg/pr81308-1.C: New test. + * g++.dg/pr81308-2.C: New test. + 2018-01-08 Vidya Praveen PR target/83663 - Revert r255946 diff --git a/gcc/testsuite/g++.dg/pr81308-1.C b/gcc/testsuite/g++.dg/pr81308-1.C new file mode 100644 index 00000000000..508372bf5e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr81308-1.C @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-options "-w -O2 -fno-exceptions -std=c++11 -fpermissive" } */ + +namespace a { +template struct d { static constexpr b e = c; }; +template struct f : d {}; +} +typedef long g; +template struct h { static const bool e = a::f::e; }; +namespace a { +template struct ah; +template class ai; +} +class i { +public: + operator[](long) const {} +}; +template class am : public i {}; +class an; +class k : public am, h>>::e> {}; +class l { +public: + aq(); +}; +class ar extern as; +typedef k at; +class m { + virtual bool av(int, unsigned &, at &, int &, g &, bool); +}; +class ar { +public: + typedef m *aw(const &, int &, const &, const &); +}; +struct ax { + static ay(ar::aw); +}; +template struct n { + n(ar) { ax::ay(ba); } + static m *ba(const &bb, int &bc, const &bd, const &be) { az(bb, bc, bd, be); } +}; +namespace { +class G : m { + unsigned bi(const at &, l &); + bool av(int, unsigned &, at &, int &, g &, bool); + +public: + G(const, int, const, const) {} +}; +} +bool G::av(int, unsigned &, at &bl, int &, g &, bool) { + l bo; + bi(bl, bo); +} +o() { n bp(as); } +namespace { +enum { bq, br }; +} +unsigned G::bi(const at &bl, l &bo) { + unsigned bs; + for (char *j;; j += 2) + switch (*j) { + case bq: + bl[bs]; + case br: + bo.aq(); + } +} diff --git a/gcc/testsuite/g++.dg/pr81308-2.C b/gcc/testsuite/g++.dg/pr81308-2.C new file mode 100644 index 00000000000..97e3409e06c --- /dev/null +++ b/gcc/testsuite/g++.dg/pr81308-2.C @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-w -O2" } */ + +struct A { + int operator[](int) const {} +}; +struct B { + void m_fn1(); +}; +struct C { + virtual bool m_fn2(int, unsigned &, A &, int &, unsigned long &, bool); +}; +template struct D { + D(int) { MCAsmParserImpl(0, 0, 0, 0); } +}; +int a; +namespace { +struct F : C { + bool m_fn2(int, unsigned &, A &, int &, unsigned long &, bool); + unsigned m_fn3(const A &, B &); + F(int, int, int, int) {} +}; +} +bool F::m_fn2(int, unsigned &, A &p3, int &, unsigned long &, bool) { + B b; + m_fn3(p3, b); +} +void fn1() { D(0); } +unsigned F::m_fn3(const A &p1, B &p2) { + for (int *p;; p++) + switch (*p) { + case 0: + p1[a]; + case 1: + p2.m_fn1(); + } +} + diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index fdec59e901d..c2538908340 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -60,6 +60,10 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA targetm.case_values_threshold(), or be its own param. */ #define MAX_CASE_BIT_TESTS 3 +/* Track whether or not we have altered the CFG and thus may need to + cleanup the CFG when complete. */ +bool cfg_altered; + /* Split the basic block at the statement pointed to by GSIP, and insert a branch to the target basic block of E_TRUE conditional on tree expression COND. @@ -1492,7 +1496,7 @@ process_switch (gswitch *swtch) /* Group case labels so that we get the right results from the heuristics that decide on the code generation approach for this switch. */ - group_case_labels_stmt (swtch); + cfg_altered |= group_case_labels_stmt (swtch); /* If this switch is now a degenerate case with only a default label, there is nothing left for us to do. */ @@ -1605,6 +1609,7 @@ pass_convert_switch::execute (function *fun) { basic_block bb; + cfg_altered = false; FOR_EACH_BB_FN (bb, fun) { const char *failure_reason; @@ -1625,6 +1630,7 @@ pass_convert_switch::execute (function *fun) failure_reason = process_switch (as_a (stmt)); if (! failure_reason) { + cfg_altered = true; if (dump_file) { fputs ("Switch converted\n", dump_file); @@ -1648,7 +1654,7 @@ pass_convert_switch::execute (function *fun) } } - return 0; + return cfg_altered ? TODO_cleanup_cfg : 0; } } // anon namespace -- 2.30.2