Message ID | 52E1881B.7020009@redhat.com |
---|---|
State | New |
Headers | show |
On Thu, Jan 23, 2014 at 02:22:35PM -0700, Jeff Law wrote: > --- a/gcc/tree-vrp.c > +++ b/gcc/tree-vrp.c > @@ -5891,8 +5891,13 @@ find_assert_locations_1 (basic_block bb, sbitmap live) > } > } > > - register_new_assert_for (op, op, comp_code, value, bb, NULL, si); > - need_assert = true; > + /* Do not register any assertions for a non-returning call. */ > + if (!is_gimple_call (stmt) || !gimple_call_noreturn_p (stmt)) > + { > + register_new_assert_for (op, op, comp_code, > + value, bb, NULL, si); > + need_assert = true; > + } > } > } I'd say this belongs into infer_value_range instead. It has: /* If STMT is the last statement of a basic block with no successors, there is no point inferring anything about any of its operands. We would not be able to find a proper insertion point for the assertion, anyway. */ if (stmt_ends_bb_p (stmt) && EDGE_COUNT (gimple_bb (stmt)->succs) == 0) return false; so I'd say it should instead do: if (stmt_ends_bb_p (stmt)) { edge_iterator ei; edge e; FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs) if (!(e->flags & EDGE_ABNORMAL)) break; if (e == NULL) return false; } Because, there are e.g. two register_new_assert_for calls with non-NULL bb and NULL e, so you'd need to handle this for both, etc. Jakub
On 01/24/14 03:52, Jakub Jelinek wrote: > On Thu, Jan 23, 2014 at 02:22:35PM -0700, Jeff Law wrote: >> --- a/gcc/tree-vrp.c >> +++ b/gcc/tree-vrp.c >> @@ -5891,8 +5891,13 @@ find_assert_locations_1 (basic_block bb, sbitmap live) >> } >> } >> >> - register_new_assert_for (op, op, comp_code, value, bb, NULL, si); >> - need_assert = true; >> + /* Do not register any assertions for a non-returning call. */ >> + if (!is_gimple_call (stmt) || !gimple_call_noreturn_p (stmt)) >> + { >> + register_new_assert_for (op, op, comp_code, >> + value, bb, NULL, si); >> + need_assert = true; >> + } >> } >> } > > I'd say this belongs into infer_value_range instead. Seems reasonable. I'll spin that. The only downside is we lose the ability to backward propagate through a typecast which feeds an argument in such a call. But that's probably not a big deal. Jeff
On Fri, Jan 24, 2014 at 09:35:10AM -0700, Jeff Law wrote: > On 01/24/14 03:52, Jakub Jelinek wrote: > >On Thu, Jan 23, 2014 at 02:22:35PM -0700, Jeff Law wrote: > >>--- a/gcc/tree-vrp.c > >>+++ b/gcc/tree-vrp.c > >>@@ -5891,8 +5891,13 @@ find_assert_locations_1 (basic_block bb, sbitmap live) > >> } > >> } > >> > >>- register_new_assert_for (op, op, comp_code, value, bb, NULL, si); > >>- need_assert = true; > >>+ /* Do not register any assertions for a non-returning call. */ > >>+ if (!is_gimple_call (stmt) || !gimple_call_noreturn_p (stmt)) > >>+ { > >>+ register_new_assert_for (op, op, comp_code, > >>+ value, bb, NULL, si); > >>+ need_assert = true; > >>+ } > >> } > >> } > > > >I'd say this belongs into infer_value_range instead. > Seems reasonable. I'll spin that. > > The only downside is we lose the ability to backward propagate > through a typecast which feeds an argument in such a call. But > that's probably not a big deal. I couldn't actually reproduce any backwards propagation, since now all pointer casts are useless, so the code to walk the pointer casts is likely just dead. Jakub
On 01/24/14 09:41, Jakub Jelinek wrote: >> >> The only downside is we lose the ability to backward propagate >> through a typecast which feeds an argument in such a call. But >> that's probably not a big deal. > > I couldn't actually reproduce any backwards propagation, > since now all pointer casts are useless, so the code to walk the pointer > casts is likely just dead. I ran across some not terribly long ago and added similar code to DOM. You just need to try harder :-) jeff
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2998c72..e27f5b1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-01-23 Jeff Law <law@redhat.com> + + PR tree-optimization/59919 + * tree-vrp.c (find_assert_locations_1): Do not register asserts + for non-returning calls. + 2014-01-23 Pat Haugen <pthaugen@us.ibm.com> * config/rs6000/rs6000.c (rs6000_option_override_internal): Don't diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 564d425..44e135a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-01-23 Jeff Law <law@redhat.com> + + PR tree-optimization/59919 + * gcc.c-torture/compile/pr59919.c: New test. + 2014-01-23 Paolo Carlini <paolo.carlini@oracle.com> PR c++/58980 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr59919.c b/gcc/testsuite/gcc.c-torture/compile/pr59919.c new file mode 100644 index 0000000..6809caa --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr59919.c @@ -0,0 +1,18 @@ +typedef int jmp_buf[10]; +struct S +{ + int i; + jmp_buf buf; +}; + +void setjmp (jmp_buf); +void foo (int *); +__attribute__ ((__noreturn__, __nonnull__)) void bar (struct S *); + +void +baz (struct S *p) +{ + bar (p); + setjmp (p->buf); + foo (&p->i); +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index f6da192..3d43d93 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -5891,8 +5891,13 @@ find_assert_locations_1 (basic_block bb, sbitmap live) } } - register_new_assert_for (op, op, comp_code, value, bb, NULL, si); - need_assert = true; + /* Do not register any assertions for a non-returning call. */ + if (!is_gimple_call (stmt) || !gimple_call_noreturn_p (stmt)) + { + register_new_assert_for (op, op, comp_code, + value, bb, NULL, si); + need_assert = true; + } } }