aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDenis Chertykov <chertykov@gmail.com>2025-01-21 00:27:04 +0400
committerDenis Chertykov <chertykov@gmail.com>2025-01-21 00:27:04 +0400
commit5cd4605141b8b45cab95e4de8005c69273071107 (patch)
tree11242609edbbf95c8cc1c8ddfd94a7e90015a792 /gcc
parent96f4ba4d19a765902af7b79aa77d52c62fa2f82c (diff)
downloadgcc-5cd4605141b8b45cab95e4de8005c69273071107.zip
gcc-5cd4605141b8b45cab95e4de8005c69273071107.tar.gz
gcc-5cd4605141b8b45cab95e4de8005c69273071107.tar.bz2
[PR117868][LRA]: Restrict the reuse of spill slots
This is an LRA bug derived from reuse spilling slots after frame pointer spilling. The slot was created for QImode (1 byte) and it was reused after spilling of the frame pointer for TImode register (16 bytes long) and it overlaps other slots. Wrong things happened while `lra_spill ()' ---------------------------- part of lra-spills.cc ---------------------------- n = assign_spill_hard_regs (pseudo_regnos, n); slots_num = 0; assign_stack_slot_num_and_sort_pseudos (pseudo_regnos, n); <--- first call --- for (i = 0; i < n; i++) if (pseudo_slots[pseudo_regnos[i]].mem == NULL_RTX) assign_mem_slot (pseudo_regnos[i]); if ((n2 = lra_update_fp2sp_elimination (pseudo_regnos)) > 0) { /* Assign stack slots to spilled pseudos assigned to fp. */ assign_stack_slot_num_and_sort_pseudos (pseudo_regnos, n2); <--- second call --- for (i = 0; i < n2; i++) if (pseudo_slots[pseudo_regnos[i]].mem == NULL_RTX) assign_mem_slot (pseudo_regnos[i]); } ------------------------------------------------------------------------------ In a first call of `assign_stack_slot_num_and_sort_pseudos(...)' LRA allocates slot #17 for r93 (QImode - 1 byte). In a second call of `assign_stack_slot_num_and_sort_pseudos(...)' LRA reuse slot #17 for r114 (TImode - 16 bytes). It's wrong. We can't reuse 1 byte slot #17 for 16 bytes register. The code in patch does reuse slots only without allocated memory or only with equal or smaller registers with equal or smaller alignment. Also, a small fix for debugging output of slot width. Print slot size as width, not a 0 as a size of (mem/c:BLK (...)). PR rtl-optimization/117868 gcc/ * lra-spills.cc (assign_stack_slot_num_and_sort_pseudos): Reuse slots only without allocated memory or only with equal or smaller registers with equal or smaller alignment. (lra_spill): Print slot size as width.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/lra-spills.cc16
1 files changed, 13 insertions, 3 deletions
diff --git a/gcc/lra-spills.cc b/gcc/lra-spills.cc
index db78dcd..93a0c92 100644
--- a/gcc/lra-spills.cc
+++ b/gcc/lra-spills.cc
@@ -386,7 +386,18 @@ assign_stack_slot_num_and_sort_pseudos (int *pseudo_regnos, int n)
&& ! (lra_intersected_live_ranges_p
(slots[j].live_ranges,
lra_reg_info[regno].live_ranges)))
- break;
+ {
+ /* A slot without allocated memory can be shared. */
+ if (slots[j].mem == NULL_RTX)
+ break;
+
+ /* A slot with allocated memory can be shared only with equal
+ or smaller register with equal or smaller alignment. */
+ if (slots[j].align >= spill_slot_alignment (mode)
+ && compare_sizes_for_sort (slots[j].size,
+ GET_MODE_SIZE (mode)) != -1)
+ break;
+ }
}
if (j >= slots_num)
{
@@ -656,8 +667,7 @@ lra_spill (void)
for (i = 0; i < slots_num; i++)
{
fprintf (lra_dump_file, " Slot %d regnos (width = ", i);
- print_dec (GET_MODE_SIZE (GET_MODE (slots[i].mem)),
- lra_dump_file, SIGNED);
+ print_dec (slots[i].size, lra_dump_file, SIGNED);
fprintf (lra_dump_file, "):");
for (curr_regno = slots[i].regno;;
curr_regno = pseudo_slots[curr_regno].next - pseudo_slots)