This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PR rtl-optimization/55604]: fix ICE in remove_some_program_points_and_update_live_ranges
- From: Steven Bosscher <stevenb dot gcc at gmail dot com>
- To: Vladimir Makarov <vmakarov at redhat dot com>
- Cc: Aldy Hernandez <aldyh at redhat dot com>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 5 Dec 2012 20:11:05 +0100
- Subject: Re: [PR rtl-optimization/55604]: fix ICE in remove_some_program_points_and_update_live_ranges
- References: <50BF8ECF.4010804@redhat.com> <50BF96DA.8010100@redhat.com>
On Wed, Dec 5, 2012 at 7:47 PM, Vladimir Makarov wrote:
> On 12-12-05 1:13 PM, Aldy Hernandez wrote:
>>
>> This is a division by zero ICE.
>>
>> In the testcase in the PR, both `n' and `lra_live_max_point' are zero. I
>> have opted to inhibit the dump when lra_live_max_point is zero, but I can
>> just as easily avoiding printing the percentage in this case.
>>
> Interesting. I never thought that is possible.
>
>> Let me know what you prefer.
>>
>> OK for trunk?
>
> Yes, it is ok if you add the testcase for GCC testsuite.
Eh, are you sure?
This means we enter remove_some_program_points_and_update_live_ranges
with lra_live_max_point==0 (it's updated _after_ compression so at the
point of the dump it's using the value on entry, _before_
compression). So we're doing things like:
born = sbitmap_alloc (lra_live_max_point); // => sbitmap_alloc (0);
dead = sbitmap_alloc (lra_live_max_point); // idem
bitmap_clear (born); // clear a bitmap that doesn't really exit
bitmap_clear (dead); // idem.
max_regno = max_reg_num ();
for (i = FIRST_PSEUDO_REGISTER; i < (unsigned) max_regno; i++)
{ // walk all registers on looking for live ranges -- but there
can't be any
for (r = lra_reg_info[i].live_ranges; r != NULL; r = r->next)
{
lra_assert (r->start <= r->finish);
bitmap_set_bit (born, r->start);
bitmap_set_bit (dead, r->finish);
}
}
etc.
That makes no sense...
The function that triggers this, has this RTL after IRA:
1: NOTE_INSN_DELETED
3: NOTE_INSN_BASIC_BLOCK 2
2: NOTE_INSN_FUNCTION_BEG
5: {r60:DI=frame:DI-0x10;clobber flags:CC;}
REG_UNUSED flags:CC
REG_EQUIV frame:DI-0x10
6: dx:DI=r60:DI
REG_DEAD r60:DI
REG_EQUAL frame:DI-0x10
7: si:SI=0x5
8: di:DI=`*.LC0'
9: ax:QI=0
10: ax:SI=call [`printf'] argc:0
REG_DEAD di:DI
REG_DEAD si:SI
REG_DEAD dx:DI
REG_UNUSED ax:SI
15: ax:SI=0
18: use ax:SI
Note how there are no pseudos at all in the function. So why run LRA
on it at all?
How about the fix proposed below?
Ciao!
Steven
Index: lra-lives.c
===================================================================
--- lra-lives.c (revision 194226)
+++ lra-lives.c (working copy)
@@ -915,6 +915,7 @@ lra_create_live_ranges (bool all_p)
basic_block bb;
int i, hard_regno, max_regno = max_reg_num ();
int curr_point;
+ bool have_referenced_pseudos = false;
timevar_push (TV_LRA_CREATE_LIVE_RANGES);
@@ -947,10 +948,24 @@ lra_create_live_ranges (bool all_p)
lra_reg_info[i].call_p = false;
#endif
if (i >= FIRST_PSEUDO_REGISTER
- && lra_reg_info[i].nrefs != 0 && (hard_regno = reg_renumber[i]) >= 0)
- lra_hard_reg_usage[hard_regno] += lra_reg_info[i].freq;
+ && lra_reg_info[i].nrefs != 0)
+ {
+ if ((hard_regno = reg_renumber[i]) >= 0)
+ lra_hard_reg_usage[hard_regno] += lra_reg_info[i].freq;
+ have_referenced_pseudos = true;
+ }
}
lra_free_copies ();
+
+ /* Under some circumstances, we can have functions without pseudo
+ registers. For such functions, lra_live_max_point will be 0,
+ see e.g. PR55604, and there's nothing more to do for us here. */
+ if (! have_referenced_pseudos)
+ {
+ timevar_pop (TV_LRA_CREATE_LIVE_RANGES);
+ return;
+ }
+
pseudos_live = sparseset_alloc (max_regno);
pseudos_live_through_calls = sparseset_alloc (max_regno);
pseudos_live_through_setjumps = sparseset_alloc (max_regno);
@@ -973,6 +988,7 @@ lra_create_live_ranges (bool all_p)
}
free (post_order_rev_cfg);
lra_live_max_point = curr_point;
+ gcc_checking_assert (lra_live_max_point > 0);
if (lra_dump_file != NULL)
print_live_ranges (lra_dump_file);
/* Clean up. */