Message ID | 20150821105233.GJ2729@redhat.com |
---|---|
State | New |
Headers | show |
On Fri, Aug 21, 2015 at 12:52 PM, Marek Polacek <polacek@redhat.com> wrote: > This fixes the libgo breakage. Seems I really should have removed the > edge after we split the block with null dereference after __builtin_trap > statement so that it's unreachable. > > Bootstrapped/regtested on x86_64-linux + ppc64-linux + bootstrapped on > aarch64-linux, ok for trunk? Hum. I don't see why this is needed - CFG cleanup (which of course needs to run!) should do this for you. In fact stray unreachable blocks are usually more of a problem. Richard. > 2015-08-21 Marek Polacek <polacek@redhat.com> > > PR tree-optimization/67284 > * gimple-ssa-isolate-paths.c (insert_trap): Remove the edge after > we split a block. > > diff --git gcc/gimple-ssa-isolate-paths.c gcc/gimple-ssa-isolate-paths.c > index ca2322d..5ac61d3 100644 > --- gcc/gimple-ssa-isolate-paths.c > +++ gcc/gimple-ssa-isolate-paths.c > @@ -115,7 +115,8 @@ insert_trap (gimple_stmt_iterator *si_p, tree op) > else > gsi_insert_before (si_p, seq, GSI_NEW_STMT); > > - split_block (gimple_bb (new_stmt), new_stmt); > + edge e = split_block (gimple_bb (new_stmt), new_stmt); > + remove_edge (e); > *si_p = gsi_for_stmt (stmt); > } > > > Marek
On Fri, Aug 21, 2015 at 01:27:43PM +0200, Richard Biener wrote: > On Fri, Aug 21, 2015 at 12:52 PM, Marek Polacek <polacek@redhat.com> wrote: > > This fixes the libgo breakage. Seems I really should have removed the > > edge after we split the block with null dereference after __builtin_trap > > statement so that it's unreachable. > > > > Bootstrapped/regtested on x86_64-linux + ppc64-linux + bootstrapped on > > aarch64-linux, ok for trunk? > > Hum. I don't see why this is needed - CFG cleanup (which of course needs > to run!) should do this for you. In fact stray unreachable blocks are usually > more of a problem. Aha. It seems cleanup does that if I change the code to generate __builtin_unreachable instead of __builtin_trap. A hint maybe? ;) What's going on here is that we find a potential NULL dereference (PHI argument has NULL), we call isolate_path, that duplicates a bb and then cuts off the outgoing edges of this duplicated bb. And in some cases it leaves COND_EXPR at the end of the bb -> ICE. The we insert __builtin_trap on this isolated path. Marek
On Fri, Aug 21, 2015 at 2:49 PM, Marek Polacek <polacek@redhat.com> wrote: > On Fri, Aug 21, 2015 at 01:27:43PM +0200, Richard Biener wrote: >> On Fri, Aug 21, 2015 at 12:52 PM, Marek Polacek <polacek@redhat.com> wrote: >> > This fixes the libgo breakage. Seems I really should have removed the >> > edge after we split the block with null dereference after __builtin_trap >> > statement so that it's unreachable. >> > >> > Bootstrapped/regtested on x86_64-linux + ppc64-linux + bootstrapped on >> > aarch64-linux, ok for trunk? >> >> Hum. I don't see why this is needed - CFG cleanup (which of course needs >> to run!) should do this for you. In fact stray unreachable blocks are usually >> more of a problem. > > Aha. It seems cleanup does that if I change the code to generate > __builtin_unreachable instead of __builtin_trap. A hint maybe? ;) Not really... static bool cleanup_control_flow_bb (basic_block bb) { ... /* Check for indirect calls that have been turned into noreturn calls. */ else if (is_gimple_call (stmt) && gimple_call_noreturn_p (stmt) && remove_fallthru_edge (bb->succs)) retval = true; and __builtin_trap is NORETURN. But there is the hint where to debug. Richard. > What's going on here is that we find a potential NULL dereference > (PHI argument has NULL), we call isolate_path, that duplicates a bb > and then cuts off the outgoing edges of this duplicated bb. And in > some cases it leaves COND_EXPR at the end of the bb -> ICE. > The we insert __builtin_trap on this isolated path. > > Marek
On Fri, Aug 21, 2015 at 03:37:38PM +0200, Richard Biener wrote: > On Fri, Aug 21, 2015 at 2:49 PM, Marek Polacek <polacek@redhat.com> wrote: > > On Fri, Aug 21, 2015 at 01:27:43PM +0200, Richard Biener wrote: > >> On Fri, Aug 21, 2015 at 12:52 PM, Marek Polacek <polacek@redhat.com> wrote: > >> > This fixes the libgo breakage. Seems I really should have removed the > >> > edge after we split the block with null dereference after __builtin_trap > >> > statement so that it's unreachable. > >> > > >> > Bootstrapped/regtested on x86_64-linux + ppc64-linux + bootstrapped on > >> > aarch64-linux, ok for trunk? > >> > >> Hum. I don't see why this is needed - CFG cleanup (which of course needs > >> to run!) should do this for you. In fact stray unreachable blocks are usually > >> more of a problem. > > > > Aha. It seems cleanup does that if I change the code to generate > > __builtin_unreachable instead of __builtin_trap. A hint maybe? ;) > > Not really... > > static bool > cleanup_control_flow_bb (basic_block bb) > { > ... > /* Check for indirect calls that have been turned into > noreturn calls. */ > else if (is_gimple_call (stmt) > && gimple_call_noreturn_p (stmt) > && remove_fallthru_edge (bb->succs)) > retval = true; > > and __builtin_trap is NORETURN. But there is the hint where to debug. Yes, but gimple_call_noreturn_p is false on __builtin_trap. That's quite confusing... but flags_from_decl_or_type really returns 0 for __builtin_trap. So can't we use __builtin_unreachable in isolate-path code? Marek
On 08/21/2015 08:41 AM, Marek Polacek wrote: > On Fri, Aug 21, 2015 at 03:37:38PM +0200, Richard Biener wrote: >> On Fri, Aug 21, 2015 at 2:49 PM, Marek Polacek <polacek@redhat.com> wrote: >>> On Fri, Aug 21, 2015 at 01:27:43PM +0200, Richard Biener wrote: >>>> On Fri, Aug 21, 2015 at 12:52 PM, Marek Polacek <polacek@redhat.com> wrote: >>>>> This fixes the libgo breakage. Seems I really should have removed the >>>>> edge after we split the block with null dereference after __builtin_trap >>>>> statement so that it's unreachable. >>>>> >>>>> Bootstrapped/regtested on x86_64-linux + ppc64-linux + bootstrapped on >>>>> aarch64-linux, ok for trunk? >>>> >>>> Hum. I don't see why this is needed - CFG cleanup (which of course needs >>>> to run!) should do this for you. In fact stray unreachable blocks are usually >>>> more of a problem. >>> >>> Aha. It seems cleanup does that if I change the code to generate >>> __builtin_unreachable instead of __builtin_trap. A hint maybe? ;) >> >> Not really... >> >> static bool >> cleanup_control_flow_bb (basic_block bb) >> { >> ... >> /* Check for indirect calls that have been turned into >> noreturn calls. */ >> else if (is_gimple_call (stmt) >> && gimple_call_noreturn_p (stmt) >> && remove_fallthru_edge (bb->succs)) >> retval = true; >> >> and __builtin_trap is NORETURN. But there is the hint where to debug. > > Yes, but gimple_call_noreturn_p is false on __builtin_trap. That's quite > confusing... but flags_from_decl_or_type really returns 0 for __builtin_trap. > > So can't we use __builtin_unreachable in isolate-path code? No, we really want the trap to halt execution rather than executing whatever code is following in the instruction stream. The latter is a significant security problem. jeff
On 08/21/2015 08:41 AM, Marek Polacek wrote: > On Fri, Aug 21, 2015 at 03:37:38PM +0200, Richard Biener wrote: >> On Fri, Aug 21, 2015 at 2:49 PM, Marek Polacek <polacek@redhat.com> wrote: >>> On Fri, Aug 21, 2015 at 01:27:43PM +0200, Richard Biener wrote: >>>> On Fri, Aug 21, 2015 at 12:52 PM, Marek Polacek <polacek@redhat.com> wrote: >>>>> This fixes the libgo breakage. Seems I really should have removed the >>>>> edge after we split the block with null dereference after __builtin_trap >>>>> statement so that it's unreachable. >>>>> >>>>> Bootstrapped/regtested on x86_64-linux + ppc64-linux + bootstrapped on >>>>> aarch64-linux, ok for trunk? >>>> >>>> Hum. I don't see why this is needed - CFG cleanup (which of course needs >>>> to run!) should do this for you. In fact stray unreachable blocks are usually >>>> more of a problem. >>> >>> Aha. It seems cleanup does that if I change the code to generate >>> __builtin_unreachable instead of __builtin_trap. A hint maybe? ;) >> >> Not really... >> >> static bool >> cleanup_control_flow_bb (basic_block bb) >> { >> ... >> /* Check for indirect calls that have been turned into >> noreturn calls. */ >> else if (is_gimple_call (stmt) >> && gimple_call_noreturn_p (stmt) >> && remove_fallthru_edge (bb->succs)) >> retval = true; >> >> and __builtin_trap is NORETURN. But there is the hint where to debug. > > Yes, but gimple_call_noreturn_p is false on __builtin_trap. That's quite > confusing... but flags_from_decl_or_type really returns 0 for __builtin_trap. Well, if that's intentional (and offhand I have no idea if it is), then you could emit a __builtin_trap followed by a __builtin_unreachable. jeff
On August 21, 2015 5:09:46 PM GMT+02:00, Jeff Law <law@redhat.com> wrote: >On 08/21/2015 08:41 AM, Marek Polacek wrote: >> On Fri, Aug 21, 2015 at 03:37:38PM +0200, Richard Biener wrote: >>> On Fri, Aug 21, 2015 at 2:49 PM, Marek Polacek <polacek@redhat.com> >wrote: >>>> On Fri, Aug 21, 2015 at 01:27:43PM +0200, Richard Biener wrote: >>>>> On Fri, Aug 21, 2015 at 12:52 PM, Marek Polacek ><polacek@redhat.com> wrote: >>>>>> This fixes the libgo breakage. Seems I really should have >removed the >>>>>> edge after we split the block with null dereference after >__builtin_trap >>>>>> statement so that it's unreachable. >>>>>> >>>>>> Bootstrapped/regtested on x86_64-linux + ppc64-linux + >bootstrapped on >>>>>> aarch64-linux, ok for trunk? >>>>> >>>>> Hum. I don't see why this is needed - CFG cleanup (which of >course needs >>>>> to run!) should do this for you. In fact stray unreachable blocks >are usually >>>>> more of a problem. >>>> >>>> Aha. It seems cleanup does that if I change the code to generate >>>> __builtin_unreachable instead of __builtin_trap. A hint maybe? ;) >>> >>> Not really... >>> >>> static bool >>> cleanup_control_flow_bb (basic_block bb) >>> { >>> ... >>> /* Check for indirect calls that have been turned into >>> noreturn calls. */ >>> else if (is_gimple_call (stmt) >>> && gimple_call_noreturn_p (stmt) >>> && remove_fallthru_edge (bb->succs)) >>> retval = true; >>> >>> and __builtin_trap is NORETURN. But there is the hint where to >debug. >> >> Yes, but gimple_call_noreturn_p is false on __builtin_trap. That's >quite >> confusing... but flags_from_decl_or_type really returns 0 for >__builtin_trap. >Well, if that's intentional (and offhand I have no idea if it is), then > >you could emit a __builtin_trap followed by a __builtin_unreachable. Looking at builtins.def I'd say it should be no return. Richard. >jeff
On August 21, 2015 5:09:46 PM GMT+02:00, Jeff Law <law@redhat.com> wrote: >On 08/21/2015 08:41 AM, Marek Polacek wrote: >> On Fri, Aug 21, 2015 at 03:37:38PM +0200, Richard Biener wrote: >>> On Fri, Aug 21, 2015 at 2:49 PM, Marek Polacek <polacek@redhat.com> >wrote: >>>> On Fri, Aug 21, 2015 at 01:27:43PM +0200, Richard Biener wrote: >>>>> On Fri, Aug 21, 2015 at 12:52 PM, Marek Polacek ><polacek@redhat.com> wrote: >>>>>> This fixes the libgo breakage. Seems I really should have >removed the >>>>>> edge after we split the block with null dereference after >__builtin_trap >>>>>> statement so that it's unreachable. >>>>>> >>>>>> Bootstrapped/regtested on x86_64-linux + ppc64-linux + >bootstrapped on >>>>>> aarch64-linux, ok for trunk? >>>>> >>>>> Hum. I don't see why this is needed - CFG cleanup (which of >course needs >>>>> to run!) should do this for you. In fact stray unreachable blocks >are usually >>>>> more of a problem. >>>> >>>> Aha. It seems cleanup does that if I change the code to generate >>>> __builtin_unreachable instead of __builtin_trap. A hint maybe? ;) >>> >>> Not really... >>> >>> static bool >>> cleanup_control_flow_bb (basic_block bb) >>> { >>> ... >>> /* Check for indirect calls that have been turned into >>> noreturn calls. */ >>> else if (is_gimple_call (stmt) >>> && gimple_call_noreturn_p (stmt) >>> && remove_fallthru_edge (bb->succs)) >>> retval = true; >>> >>> and __builtin_trap is NORETURN. But there is the hint where to >debug. >> >> Yes, but gimple_call_noreturn_p is false on __builtin_trap. That's >quite >> confusing... but flags_from_decl_or_type really returns 0 for >__builtin_trap. >Well, if that's intentional (and offhand I have no idea if it is), then > >you could emit a __builtin_trap followed by a __builtin_unreachable. But maybe go is non-call-exceptions and that makes a difference? >jeff
diff --git gcc/gimple-ssa-isolate-paths.c gcc/gimple-ssa-isolate-paths.c index ca2322d..5ac61d3 100644 --- gcc/gimple-ssa-isolate-paths.c +++ gcc/gimple-ssa-isolate-paths.c @@ -115,7 +115,8 @@ insert_trap (gimple_stmt_iterator *si_p, tree op) else gsi_insert_before (si_p, seq, GSI_NEW_STMT); - split_block (gimple_bb (new_stmt), new_stmt); + edge e = split_block (gimple_bb (new_stmt), new_stmt); + remove_edge (e); *si_p = gsi_for_stmt (stmt); }