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
This commit is contained in:
parent
b9a4d2ba48
commit
5a2a87e1e2
@ -1,5 +1,12 @@
|
||||
2017-01-08 Jeff Law <law@redhat.com>
|
||||
|
||||
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.
|
||||
|
@ -1,3 +1,9 @@
|
||||
2018-01-08 Jeff Law <law@redhat.com>
|
||||
|
||||
PR rtl-optimizatin/81308
|
||||
* g++.dg/pr81308-1.C: New test.
|
||||
* g++.dg/pr81308-2.C: New test.
|
||||
|
||||
2018-01-08 Vidya Praveen <vidyapraveen@arm.com>
|
||||
|
||||
PR target/83663 - Revert r255946
|
||||
|
67
gcc/testsuite/g++.dg/pr81308-1.C
Normal file
67
gcc/testsuite/g++.dg/pr81308-1.C
Normal file
@ -0,0 +1,67 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-w -O2 -fno-exceptions -std=c++11 -fpermissive" } */
|
||||
|
||||
namespace a {
|
||||
template <typename b, b c> struct d { static constexpr b e = c; };
|
||||
template <typename> struct f : d<bool, __is_trivially_copyable(int)> {};
|
||||
}
|
||||
typedef long g;
|
||||
template <typename> struct h { static const bool e = a::f<int>::e; };
|
||||
namespace a {
|
||||
template <typename> struct ah;
|
||||
template <typename> class ai;
|
||||
}
|
||||
class i {
|
||||
public:
|
||||
operator[](long) const {}
|
||||
};
|
||||
template <typename, int> class am : public i {};
|
||||
class an;
|
||||
class k : public am<a::ai<an>, h<a::ai<a::ah<an>>>::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 <class az> 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<G> 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();
|
||||
}
|
||||
}
|
38
gcc/testsuite/g++.dg/pr81308-2.C
Normal file
38
gcc/testsuite/g++.dg/pr81308-2.C
Normal file
@ -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 <class MCAsmParserImpl> 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<F>(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();
|
||||
}
|
||||
}
|
||||
|
@ -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 <gswitch *> (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
|
||||
|
Loading…
Reference in New Issue
Block a user