re PR rtl-optimization/87305 (Segfault in end_hard_regno in setup_live_pseudos_and_spill_after_risky_transforms on aarch64 big-endian)

2019-01-10  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimization/87305
	* lra-assigns.c
	(setup_live_pseudos_and_spill_after_risky_transforms): Check
	allocation for big endian pseudos used as paradoxical subregs and
	spill them if it is wrong.
	* lra-constraints.c (lra_constraints): Add a comment.

2019-01-10  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimization/87305
	* gcc.target/aarch64/pr87305.c: New.

From-SVN: r267823
This commit is contained in:
Vladimir Makarov 2019-01-10 21:02:50 +00:00 committed by Vladimir Makarov
parent f25507d041
commit 7e4d17a846
5 changed files with 82 additions and 9 deletions

View File

@ -1,3 +1,12 @@
2019-01-10 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/87305
* lra-assigns.c
(setup_live_pseudos_and_spill_after_risky_transforms): Check
allocation for big endian pseudos used as paradoxical subregs and
spill them if it is wrong.
* lra-constraints.c (lra_constraints): Add a comment.
2019-01-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/88792

View File

@ -1146,12 +1146,12 @@ static void
setup_live_pseudos_and_spill_after_risky_transforms (bitmap
spilled_pseudo_bitmap)
{
int p, i, j, n, regno, hard_regno;
int p, i, j, n, regno, hard_regno, biggest_nregs, nregs_diff;
unsigned int k, conflict_regno;
poly_int64 offset;
int val;
HARD_REG_SET conflict_set;
machine_mode mode;
machine_mode mode, biggest_mode;
lra_live_range_t r;
bitmap_iterator bi;
int max_regno = max_reg_num ();
@ -1166,8 +1166,26 @@ setup_live_pseudos_and_spill_after_risky_transforms (bitmap
for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if ((pic_offset_table_rtx == NULL_RTX
|| i != (int) REGNO (pic_offset_table_rtx))
&& reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0)
sorted_pseudos[n++] = i;
&& (hard_regno = reg_renumber[i]) >= 0 && lra_reg_info[i].nrefs > 0)
{
biggest_mode = lra_reg_info[i].biggest_mode;
biggest_nregs = hard_regno_nregs (hard_regno, biggest_mode);
nregs_diff = (biggest_nregs
- hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (i)));
enum reg_class rclass = lra_get_allocno_class (i);
if (WORDS_BIG_ENDIAN
&& (hard_regno - nregs_diff < 0
|| !TEST_HARD_REG_BIT (reg_class_contents[rclass],
hard_regno - nregs_diff)))
{
/* Hard registers of paradoxical sub-registers are out of
range of pseudo register class. Spill the pseudo. */
reg_renumber[i] = -1;
continue;
}
sorted_pseudos[n++] = i;
}
qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func);
if (pic_offset_table_rtx != NULL_RTX
&& (regno = REGNO (pic_offset_table_rtx)) >= FIRST_PSEUDO_REGISTER
@ -1206,10 +1224,11 @@ setup_live_pseudos_and_spill_after_risky_transforms (bitmap
|| hard_regno != reg_renumber[conflict_regno])
{
int conflict_hard_regno = reg_renumber[conflict_regno];
machine_mode biggest_mode = lra_reg_info[conflict_regno].biggest_mode;
int biggest_nregs = hard_regno_nregs (conflict_hard_regno,
biggest_mode);
int nregs_diff
biggest_mode = lra_reg_info[conflict_regno].biggest_mode;
biggest_nregs = hard_regno_nregs (conflict_hard_regno,
biggest_mode);
nregs_diff
= (biggest_nregs
- hard_regno_nregs (conflict_hard_regno,
PSEUDO_REGNO_MODE (conflict_regno)));

View File

@ -4739,7 +4739,9 @@ lra_constraints (bool first_p)
else
/* On the first iteration we should check IRA assignment
correctness. In rare cases, the assignments can be wrong as
early clobbers operands are ignored in IRA. */
early clobbers operands are ignored in IRA or usages of
paradoxical sub-registers are not taken into account by
IRA. */
lra_risky_transformations_p = first_p;
new_insn_uid_start = get_max_uid ();
new_regno_start = first_p ? lra_constraint_new_regno_start : max_reg_num ();

View File

@ -1,3 +1,8 @@
2019-01-10 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/87305
* gcc.target/aarch64/pr87305.c: New.
2019-01-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/88792

View File

@ -0,0 +1,38 @@
/* { dg-do compile } */
/* { dg-options "-Ofast -mbig-endian -w" } */
int cc;
void
rc (__int128 *oi)
{
__int128 qz = (__int128)2 << cc;
if (qz != 0)
{
if (cc != 0)
{
__int128 zp = 1;
for (;;)
{
unsigned __int128 *ar = &cc;
int y5;
if (oi != 0)
{
y3:
zp = *oi + *ar;
}
y5 = (cc + 1) == ((*ar /= *oi) << ((zp >>= 128) / cc));
qz += !!y5 ? 1 : qz == (*ar ^ zp + 1);
++*oi;
}
}
else
++qz;
}
goto y3;
}