| Submitter | Jakub Jelinek |
|---|---|
| Date | June 25, 2010, 11:43 a.m. |
| Message ID | <20100625114355.GI12443@tyan-ft48-01.lab.bos.redhat.com> |
| Download | mbox | patch |
| Permalink | /patch/56902/ |
| State | New |
| Headers | show |
Comments
On Fri, 25 Jun 2010, Jakub Jelinek wrote: > Hi! > > When a call has VDEF, but doesn't have lhs and is through noreturn discovery > changed into a noreturn call, we failed to remove the VDEF, which caused > verification errors. > > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux. > Ok for trunk? Ok. Thanks, Richard. > Calling update_stmt unconditionally there isn't possible, as update_stmt > adds the stmt into MODIFIED_NORETURN_CALLS and thus > split_bbs_on_noreturn_calls hangs. If it has lhs or vdef, the first > update_stmt call changes it and the next one won't call update_stmt anymore. > > 2010-06-25 Jakub Jelinek <jakub@redhat.com> > > PR tree-optimization/44539 > * tree-cfgcleanup.c (fixup_noreturn_call): Call update_stmt even when > the call doesn't have LHS, but has VDEF. > > * gcc.dg/pr44539.c: New test. > > --- gcc/tree-cfgcleanup.c.jj 2010-06-14 07:44:24.000000000 +0200 > +++ gcc/tree-cfgcleanup.c 2010-06-24 11:44:59.000000000 +0200 > @@ -591,6 +591,9 @@ fixup_noreturn_call (gimple stmt) > update_stmt (stmt); > changed = true; > } > + /* Similarly remove VDEF if there is any. */ > + else if (gimple_vdef (stmt)) > + update_stmt (stmt); > return changed; > } > > --- gcc/testsuite/gcc.dg/pr44539.c.jj 2010-06-24 11:45:16.000000000 +0200 > +++ gcc/testsuite/gcc.dg/pr44539.c 2010-06-24 11:44:26.000000000 +0200 > @@ -0,0 +1,29 @@ > +/* PR tree-optimization/44539 */ > +/* { dg-do compile } */ > +/* { dg-options "-ftracer -freorder-blocks -O2" } */ > + > +void bar (int file); > +extern int baz (void); > + > +void noret1 () > +{ > + bar (0); > + __builtin_exit (0); > +} > + > +void noret2 () > +{ > + __builtin_exit (0); > +} > + > +void bar (int i) > +{ > + if (baz ()) > + noret1 (i); > +} > + > +void foo (int i) > +{ > + if (~i) bar (i); > + i ? noret1 () : noret2 (); > +} > > Jakub > >
Patch
--- gcc/tree-cfgcleanup.c.jj 2010-06-14 07:44:24.000000000 +0200 +++ gcc/tree-cfgcleanup.c 2010-06-24 11:44:59.000000000 +0200 @@ -591,6 +591,9 @@ fixup_noreturn_call (gimple stmt) update_stmt (stmt); changed = true; } + /* Similarly remove VDEF if there is any. */ + else if (gimple_vdef (stmt)) + update_stmt (stmt); return changed; } --- gcc/testsuite/gcc.dg/pr44539.c.jj 2010-06-24 11:45:16.000000000 +0200 +++ gcc/testsuite/gcc.dg/pr44539.c 2010-06-24 11:44:26.000000000 +0200 @@ -0,0 +1,29 @@ +/* PR tree-optimization/44539 */ +/* { dg-do compile } */ +/* { dg-options "-ftracer -freorder-blocks -O2" } */ + +void bar (int file); +extern int baz (void); + +void noret1 () +{ + bar (0); + __builtin_exit (0); +} + +void noret2 () +{ + __builtin_exit (0); +} + +void bar (int i) +{ + if (baz ()) + noret1 (i); +} + +void foo (int i) +{ + if (~i) bar (i); + i ? noret1 () : noret2 (); +}