https://gcc.gnu.org/g:5cd4605141b8b45cab95e4de8005c69273071107

commit r15-7078-g5cd4605141b8b45cab95e4de8005c69273071107
Author: Denis Chertykov <cherty...@gmail.com>
Date:   Tue Jan 21 00:27:04 2025 +0400

    [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.

Diff:
---
 gcc/lra-spills.cc | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/gcc/lra-spills.cc b/gcc/lra-spills.cc
index db78dcd28a35..93a0c92db9fa 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)

Reply via email to