On Wed, Aug 28, 2013 at 10:06 PM, Jeff Law <[email protected]> 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 <[email protected]>
>>
>> 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
>
>