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> 2019-01-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/88792 PR tree-optimization/88792

View File

@ -1146,12 +1146,12 @@ static void
setup_live_pseudos_and_spill_after_risky_transforms (bitmap setup_live_pseudos_and_spill_after_risky_transforms (bitmap
spilled_pseudo_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; unsigned int k, conflict_regno;
poly_int64 offset; poly_int64 offset;
int val; int val;
HARD_REG_SET conflict_set; HARD_REG_SET conflict_set;
machine_mode mode; machine_mode mode, biggest_mode;
lra_live_range_t r; lra_live_range_t r;
bitmap_iterator bi; bitmap_iterator bi;
int max_regno = max_reg_num (); 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++) for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if ((pic_offset_table_rtx == NULL_RTX if ((pic_offset_table_rtx == NULL_RTX
|| i != (int) REGNO (pic_offset_table_rtx)) || i != (int) REGNO (pic_offset_table_rtx))
&& reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0) && (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; sorted_pseudos[n++] = i;
}
qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func); qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func);
if (pic_offset_table_rtx != NULL_RTX if (pic_offset_table_rtx != NULL_RTX
&& (regno = REGNO (pic_offset_table_rtx)) >= FIRST_PSEUDO_REGISTER && (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]) || hard_regno != reg_renumber[conflict_regno])
{ {
int conflict_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 = lra_reg_info[conflict_regno].biggest_mode;
biggest_nregs = hard_regno_nregs (conflict_hard_regno,
biggest_mode); biggest_mode);
int nregs_diff nregs_diff
= (biggest_nregs = (biggest_nregs
- hard_regno_nregs (conflict_hard_regno, - hard_regno_nregs (conflict_hard_regno,
PSEUDO_REGNO_MODE (conflict_regno))); PSEUDO_REGNO_MODE (conflict_regno)));

View File

@ -4739,7 +4739,9 @@ lra_constraints (bool first_p)
else else
/* On the first iteration we should check IRA assignment /* On the first iteration we should check IRA assignment
correctness. In rare cases, the assignments can be wrong as 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; lra_risky_transformations_p = first_p;
new_insn_uid_start = get_max_uid (); new_insn_uid_start = get_max_uid ();
new_regno_start = first_p ? lra_constraint_new_regno_start : max_reg_num (); 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> 2019-01-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/88792 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;
}