On Wed, Aug 28, 2013 at 10:06 PM, Jeff Law <l...@redhat.com> wrote:
> On 08/28/2013 03:50 AM, Mikael Pettersson wrote:
>>
>> This patch fixes an ICE that occurs in #ifdef HAVE_cc0 code.  The ICE
>> breaks both Java and Ada bootstrap on m68k-linux.  There is also a
>> tiny C++ test case in the BZ entry.
>>
>> The ICE is triggered by the PR middle-end/50780 changes in r180192.
>> As explained in <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49847#c16>,
>> the effect of those changes is that an expression in EH context is
>> broken up so that the cc0 setter and user are put in separate BBs, which
>> normally isn't allowed.  As fold_rtx sees the cc0 user, it calls
>> equiv_constant on prev_insn_cc0, but that is NULL due to the BB boundary,
>> resulting in the ICE.
>>
>> This patch checks if prev_insn_cc0 is NULL, and if so doesn't call
>> equiv_constant but sets const_arg to zero, which avoids the ICE and
>> makes fold_rtx leave the insn unchanged.
>>
>> Bootstrapped and regtested on m68k-linux, no regressions.  This patch
>> has been in 4.6-based production compilers on m68k-linux since early 2012,
>> and in a 4.7-based compiler since early 2013.
>>
>> Ok for trunk and 4.8?
>>
>> [If approved I'll need help to commit it as I don't have commit rights.]
>>
>> gcc/
>>
>> 2013-08-28  Mikael Pettersson  <mi...@it.uu.se>
>>
>>         PR rtl-optimization/49847
>>         * cse.c (fold_rtx) <second case CC0>: If prev_insn_cc0 is NULL
>>         don't call equiv_constant on it.
>
> I can't help but feel something different needs to be done here.   It's
> always been the case that those two insns are expected to be contiguous and
> there's going to be code all over the place that makes that assumption and
> that model is what every GCC developer has expected for the last 20+ years.
>
> What precisely about Richi's patch causes the setter and user to end up in
> different blocks?  I'm guessing we now consider the comparison itself as
> potentially trapping and thus we end the block immediately?  The consumer
> then appears in the next block?

Btw, the handling for COND_EXPRs was simply adjusted to be the same
as for if () conditions.

>From looking at the testcase,

int f (float g)
{
  try { return g >= 0; }
  catch (...) {}
}

can't you simply avoid expanding throwing stuff to a set-reg-based-on-compare
instruction sequence?

Or why does the issue not trigger on

 try { if (g >= 0) return 1; else 0; } catch (...) {}

?

Richard.

> I wonder if the comparison could be duplicated and marked as non-throwing at
> RTL generation time.   Alternately (and probably better) would be to convert
> the remaining stragglers and drop the old cc0 support entirely.
>
> jeff
>
>

Reply via email to