Message ID | 20101102233609.GK29412@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On Wed, Nov 3, 2010 at 12:36 AM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > When FRE or PRE transforms a call through fn pointer into a noreturn call, > if it doesn't TODO_cleanup_cfg, we ICE in checking, because the noreturn > call hasn't been fixed up. > > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for > trunk? Ok. Thanks, Richard. > 2010-11-02 Jakub Jelinek <jakub@redhat.com> > > PR tree-optimization/46165 > * tree-ssa-pre.c (eliminate): Return TODO_cleanup_cfg if changing > a normal call into noreturn call. > > * gcc.dg/pr46165.c: New test. > > --- gcc/tree-ssa-pre.c.jj 2010-11-01 09:07:23.000000000 +0100 > +++ gcc/tree-ssa-pre.c 2010-11-02 14:27:58.000000000 +0100 > @@ -4364,6 +4364,7 @@ eliminate (void) > { > bool can_make_abnormal_goto > = stmt_can_make_abnormal_goto (stmt); > + bool was_noreturn = gimple_call_noreturn_p (stmt); > > if (dump_file && (dump_flags & TDF_DETAILS)) > { > @@ -4376,6 +4377,11 @@ eliminate (void) > gimple_call_set_fn (stmt, fn); > update_stmt (stmt); > > + /* When changing a call into a noreturn call, cfg cleanup > + is needed to fix up the noreturn call. */ > + if (!was_noreturn && gimple_call_noreturn_p (stmt)) > + todo |= TODO_cleanup_cfg; > + > /* If we removed EH side-effects from the statement, clean > its EH information. */ > if (maybe_clean_or_replace_eh_stmt (stmt, stmt)) > --- gcc/testsuite/gcc.dg/pr46165.c.jj 2010-11-02 14:47:51.000000000 +0100 > +++ gcc/testsuite/gcc.dg/pr46165.c 2010-11-02 14:47:16.000000000 +0100 > @@ -0,0 +1,11 @@ > +/* PR tree-optimization/46165 */ > +/* { dg-do compile } */ > +/* { dg-options "-O -fno-tree-ccp -fno-tree-copy-prop -fno-tree-dce" } */ > + > +extern void foo (void) __attribute__((noreturn)); > +void > +g (void) > +{ > + void (*f) (void) = foo; > + f (); > +} > > Jakub >
--- gcc/tree-ssa-pre.c.jj 2010-11-01 09:07:23.000000000 +0100 +++ gcc/tree-ssa-pre.c 2010-11-02 14:27:58.000000000 +0100 @@ -4364,6 +4364,7 @@ eliminate (void) { bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt); + bool was_noreturn = gimple_call_noreturn_p (stmt); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -4376,6 +4377,11 @@ eliminate (void) gimple_call_set_fn (stmt, fn); update_stmt (stmt); + /* When changing a call into a noreturn call, cfg cleanup + is needed to fix up the noreturn call. */ + if (!was_noreturn && gimple_call_noreturn_p (stmt)) + todo |= TODO_cleanup_cfg; + /* If we removed EH side-effects from the statement, clean its EH information. */ if (maybe_clean_or_replace_eh_stmt (stmt, stmt)) --- gcc/testsuite/gcc.dg/pr46165.c.jj 2010-11-02 14:47:51.000000000 +0100 +++ gcc/testsuite/gcc.dg/pr46165.c 2010-11-02 14:47:16.000000000 +0100 @@ -0,0 +1,11 @@ +/* PR tree-optimization/46165 */ +/* { dg-do compile } */ +/* { dg-options "-O -fno-tree-ccp -fno-tree-copy-prop -fno-tree-dce" } */ + +extern void foo (void) __attribute__((noreturn)); +void +g (void) +{ + void (*f) (void) = foo; + f (); +}