On Tue, Nov 26, 2013 at 11:05 PM, Jeff Law wrote:
> On 11/26/13 14:41, Steven Bosscher wrote:
>>
>>
>> I suppose with "cruft" you mean the dead end in the CFG due to
>> builtin_unreachable, correct?
>
> Yes.
>
>
>
> > If so, then I suppose you could also
>>
>> just let cfgcleanup handle that cruft and not wait until
>> if-conversion.
>
> But what does all this look like at the RTL level.  A block resulting from
> __builtin_unreachable is just a block with no successors.  So while we could
> clean it up in this case, I don't think we can in general.
>
> ie, we might ahve:
>
>    [ ... ]
>    fubar ();
>    __builtin_unreachable ();
>
> Where the programmer is effectively asserting that fubar never returns.

Right. I saw that one in the documentation and my first reaction was
"ECF_NORETURN". But that flag applies to functions, not call
statements.


> So we have a block which calls fubar.  The block would have no successors.
> And I think we're right back in the same situation.  We're going to have a
> BARRIER after that block with no successors and ifcvt is going to muck
> things up tripping the checking failure.

In RTL-land the NORETURN flag is already a statement thing via
REG_NORETURN. But I'm not sure if such a note is added for calls
followed originally by a builtin_unreachable. I'm guessing "not".


> Furthermore, ISTM, that while __builtin_unreachable is part of this instance
> of the problem, ultimately the core issue is that the ifcvt code doesn't
> properly handle cases where the converted blocks have no successors.

True.  It only handles cases where it can see why there are no
successors. I'm pretty sure most of the time that bit of information
is encoded somehow (trap, REG_NORETURN, etc.). As far as I'm aware,
__builtin_unreachable is the only exception.


> Arguably it could be dropped, as we expand, but then you drop useful
> information from the CFG.  Namely that certain blocks of code never rejoin
> the main control flow.  ie, once you're on that path, you're going to hang,
> abort/exit and the like.  Thus you don't need edges from those paths back to
> the main stream.

And yet, that's what merge_if_blocks will do if you remove the
BARRIER. You're basically closing the diamond so that the conditional
jump can be optimized away. That's a good thing, of course.

But it seems arbitrary to do it in ifcvt.c and only for cond_exec
targets. Does the condjump survive to assembler output on e.g. x86_64?


>> Hacking BARRIERs by hand in a function that's supposed to know about
>> the CFG just seems wrong :-(
>
> Open to other suggestions.

Can't claim to have any, at least not for short-term solutions.

Ciao!
Steven

Reply via email to