aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2019-01-10 21:02:50 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2019-01-10 21:02:50 +0000
commit7e4d17a84648b9844a8ddebe88269857ab33f4ab (patch)
tree47f1045bd356f4375b22344adfda3e7807680e26 /gcc
parentf25507d041de4df6fffabedbed57c07ecff0d9ab (diff)
downloadgcc-7e4d17a84648b9844a8ddebe88269857ab33f4ab.zip
gcc-7e4d17a84648b9844a8ddebe88269857ab33f4ab.tar.gz
gcc-7e4d17a84648b9844a8ddebe88269857ab33f4ab.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/lra-assigns.c35
-rw-r--r--gcc/lra-constraints.c4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr87305.c38
5 files changed, 82 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a0276f2..6bbcfa6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c
index 1312804..5a4e1eb 100644
--- a/gcc/lra-assigns.c
+++ b/gcc/lra-assigns.c
@@ -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)));
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 4f434e5..c08ad9a 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -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 ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ef231a2..33dd630 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.target/aarch64/pr87305.c b/gcc/testsuite/gcc.target/aarch64/pr87305.c
new file mode 100644
index 0000000..8beaa91
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr87305.c
@@ -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;
+}