From 0b75beaaaf8af46fcbd7bd9ae535a6255737b69a Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 17 Sep 2003 09:11:01 +0200 Subject: [PATCH] re PR rtl-optimization/11646 (ICE in commit_one_edge_insertion with -fnon-call-exceptions -fgcse -O) PR optimization/11646 * cfgrtl.c (purge_dead_edges) [JUMP_INSN]: Rematerialize the EDGE_ABNORMAL flag for EH edges. * toplev.c (rest_of_handle_cse): Delete unreachable blocks if dead edges were purged. From-SVN: r71455 --- gcc/ChangeLog | 8 +++++ gcc/cfgrtl.c | 8 +++-- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/g++.dg/opt/cfg3.C | 61 +++++++++++++++++++++++++++++++++ gcc/toplev.c | 3 +- 5 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/cfg3.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9062d99d2899..aa323e23d745 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2003-09-17 Eric Botcazou + + PR optimization/11646 + * cfgrtl.c (purge_dead_edges) [JUMP_INSN]: Rematerialize the + EDGE_ABNORMAL flag for EH edges. + * toplev.c (rest_of_handle_cse): Delete unreachable blocks + if dead edges were purged. + 2003-09-16 Bernardo Innocenti * config/m68k/m68k.h (TARGET_CPU_CPP_BUILTINS): Add target predefines. diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 7441cd9db59d..f383438e26b6 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -2255,8 +2255,12 @@ purge_dead_edges (basic_block bb) continue; else if ((e->flags & EDGE_EH) && can_throw_internal (insn)) /* Keep the edges that correspond to exceptions thrown by - this instruction. */ - continue; + this instruction and rematerialize the EDGE_ABNORMAL + flag we just cleared above. */ + { + e->flags |= EDGE_ABNORMAL; + continue; + } /* We do not need this edge. */ bb->flags |= BB_DIRTY; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e7cf798e7d8b..fae6be7893f9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-09-17 Eric Botcazou + + * g++.dg/opt/cfg3.C: New test. + 2003-09-16 Kriang Lerdsuwanakij PR c++/7939 diff --git a/gcc/testsuite/g++.dg/opt/cfg3.C b/gcc/testsuite/g++.dg/opt/cfg3.C new file mode 100644 index 000000000000..123c2f5157ba --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cfg3.C @@ -0,0 +1,61 @@ +// PR optimization/11646 +// Origin: + +// This used to fail because the compiler inadvertently cleared +// the EDGE_ABNORMAL flag on a EDGE_EH edge and didn't delete +// unreachable blocks after CSE. + +// { dg-do compile } +// { dg-options "-O -fgcse -fnon-call-exceptions" } + +struct C +{ + int i; +}; + +struct allocator +{ + ~allocator() throw() {} +}; + +struct _Vector_alloc_base +{ + _Vector_alloc_base(const allocator& __a) {} + allocator _M_data_allocator; + struct C *_M_start, *_M_end_of_storage; + void _M_deallocate(struct C* __p, unsigned int __n) {} +}; + +struct _Vector_base : _Vector_alloc_base +{ + _Vector_base(const allocator& __a) : _Vector_alloc_base(__a) { } + ~_Vector_base() { _M_deallocate(0, _M_end_of_storage - _M_start); } +}; + +struct vector : _Vector_base +{ + vector(const allocator& __a = allocator()) : _Vector_base(__a) {} + struct C& operator[](unsigned int __n) { return *_M_start; } +}; + +struct A +{ + float l() const; + A operator-(const A &) const; + const A& operator=(float) const; +}; + +struct B +{ + float d(); +}; + +float f(const A& a, B& b) +{ + vector vc; + int index = vc[0].i; + A aa; + float d = (aa - a).l(); + if (d > b.d()) aa = 0; + return b.d(); +} diff --git a/gcc/toplev.c b/gcc/toplev.c index bcc9c5046a99..91409bf71349 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2846,7 +2846,8 @@ rest_of_handle_cse (tree decl, rtx insns) tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file); if (tem) rebuild_jump_labels (insns); - purge_all_dead_edges (0); + if (purge_all_dead_edges (0)) + delete_unreachable_blocks (); delete_trivially_dead_insns (insns, max_reg_num ()); -- 2.43.5