mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-17 15:31:05 +08:00
tree-optimization/107876 - unswitching of switch
The following shows a missed update of dominators when unswitching removes unreachable edges from switch stmts it unswitches. Fixed by wiping dominator info in that case. PR tree-optimization/107876 * tree-ssa-loop-unswitch.cc (clean_up_after_unswitching): Wipe dominator info if we removed an edge. * g++.dg/tree-ssa/pr107876.C: New testcase.
This commit is contained in:
parent
0976b012d8
commit
238cf114de
38
gcc/testsuite/g++.dg/tree-ssa/pr107876.C
Normal file
38
gcc/testsuite/g++.dg/tree-ssa/pr107876.C
Normal file
@ -0,0 +1,38 @@
|
||||
// { dg-do compile }
|
||||
// { dg-require-effective-target c++11 }
|
||||
// { dg-options "-O2 -funswitch-loops --param max-unswitch-insns=5 -fdump-tree-unswitch-details" }
|
||||
|
||||
class X {
|
||||
public:
|
||||
X();
|
||||
X(const X&);
|
||||
X(const volatile X &);
|
||||
~X();
|
||||
};
|
||||
|
||||
X test17(int i) {
|
||||
if (false) {
|
||||
impossible:
|
||||
if (i == 3)
|
||||
return X();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
X x;
|
||||
if (i == 0)
|
||||
return x;
|
||||
if (i == 1)
|
||||
break;
|
||||
if (i == 2)
|
||||
continue;
|
||||
if (i == 3)
|
||||
goto impossible;
|
||||
if (i == 4)
|
||||
__builtin_exit(1);
|
||||
if (i == 5)
|
||||
return x;
|
||||
}
|
||||
return X();
|
||||
}
|
||||
|
||||
// { dg-final { scan-tree-dump "unswitching loop 1 on .switch. with condition: i_\[0-9\]+\\(D\\) == 2" "unswitch" } }
|
@ -1631,6 +1631,7 @@ clean_up_after_unswitching (int ignored_edge_flag)
|
||||
basic_block bb;
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
bool removed_edge = false;
|
||||
|
||||
FOR_EACH_BB_FN (bb, cfun)
|
||||
{
|
||||
@ -1655,7 +1656,10 @@ clean_up_after_unswitching (int ignored_edge_flag)
|
||||
to preserve its edge. But we can remove the
|
||||
non-default CASE sharing the edge. */
|
||||
if (e != default_e)
|
||||
remove_edge (e);
|
||||
{
|
||||
remove_edge (e);
|
||||
removed_edge = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1672,6 +1676,10 @@ clean_up_after_unswitching (int ignored_edge_flag)
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
e->flags &= ~ignored_edge_flag;
|
||||
}
|
||||
|
||||
/* If we removed an edge we possibly have to recompute dominators. */
|
||||
if (removed_edge)
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
}
|
||||
|
||||
/* Loop unswitching pass. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user