diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2019-01-10 21:02:50 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2019-01-10 21:02:50 +0000 |
commit | 7e4d17a84648b9844a8ddebe88269857ab33f4ab (patch) | |
tree | 47f1045bd356f4375b22344adfda3e7807680e26 /gcc | |
parent | f25507d041de4df6fffabedbed57c07ecff0d9ab (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/lra-assigns.c | 35 | ||||
-rw-r--r-- | gcc/lra-constraints.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/pr87305.c | 38 |
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; +} |