http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49847

--- Comment #25 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jeffrey A. Law from comment #24)
> This is a mess.
> 
> As noted in the other comments, we're considering a cc0-setter as a
> potentially trapping insn.  As a result the cc0-setter and cc0-consumer end
> up in different blocks.
>
> That's bad on so many levels and "fixing" it by hacking up fold_rtx like
> this just papers over the fundamental problem (though I must admit from a
> pragmatic standpoint, it's pretty effective).
> 
> One could argue that the CFG building code could be tweaked so that a
> cc0-setter is never considered the end of a block.  The downside of that is
> we're lying to the compiler about the true nature of the CFG.  But that
> little white lie may be acceptable.  I haven't looked into how ugly that
> would be to implement.

Well, it re-exposes the original problem of not properly handling EH
with -fnon-call-exception and trapping FP comparisons?  I don't recall
all the issues with the original case I installed the change (at least
we do consider GIMPLE_CONDs as possibly trapping, just we don't allow
a possibly throwing condition in a GIMPLE_COND).

One fix for backends where cc0 setter and consumer
may not be separated is to duplicate the comparison like

 <bb>
   ...
   g >= 0.0;     // stmt ending BB with EH edges

 <bb>
   if (g >= 0.0) // redundant compare, but with NOTHROW set
     ...

Or to revert the original change and think of a better fix.

But certainly you can't rely on the IL being

  if (g >= 0.0)

instead of (what gimplification forces now)

  bool tem = g >= 0.0;

  <bb>
    if (tem != 0)

because with -fnon-call-exceptions writing that literally in C++ and
compiling with -O0 will yield exactly the same issue as you hit it
now (separated cc0 setter / consumer).

So reverting wouldn't be a "real" fix.  Testcase:

int foo (double x)
{
  try {
      bool cond = x >= 0.0;
      if (cond)
        return 1;
      return 0;
  }
  catch (...)
    {
      return -1;
    }
}

Where we shouldn't ICE when reverting the original fix and which at -O0
produces exactly the same "issue" you face now.

Best it into a runtime testcase that properly catches a trapping compare.

Richard.

Reply via email to