https://gcc.gnu.org/g:674e2e21a612c66b098c08b49f702cf4ba4f7e18

commit 674e2e21a612c66b098c08b49f702cf4ba4f7e18
Author: Alexandre Oliva <[email protected]>
Date:   Thu Nov 20 01:55:00 2025 -0300

    ira: test stabilize allocation across word size

Diff:
---
 gcc/ira-color.cc | 38 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/gcc/ira-color.cc b/gcc/ira-color.cc
index f7b143553929..b53c6d4d1447 100644
--- a/gcc/ira-color.cc
+++ b/gcc/ira-color.cc
@@ -235,6 +235,10 @@ allocno_hard_regs_hasher::hash (const allocno_hard_regs 
*hv)
               ? TEST_HARD_REG_BIT (hv->set, FIRST_PSEUDO_REGISTER)
               : 0);
 
+#define TEST_HARD_REG_SET_HASH 1
+  bool test_hard_reg_set_hash = false;
+  size_t un, ut;
+
   if (sizeof (uint32_t) * CHAR_BIT == 32
       && (HOST_BITS_PER_WIDEST_FAST_INT % 32) == 0)
     {
@@ -250,18 +254,26 @@ allocno_hard_regs_hasher::hash (const allocno_hard_regs 
*hv)
       const size_t t = sizeof (T);
       const size_t s = t * CHAR_BIT;
       const size_t n = (FIRST_PSEUDO_REGISTER + s - 1) / s;
+#if TEST_HARD_REG_SET_HASH
+      test_hard_reg_set_hash = true; un = n; ut = t;
+#endif
 #ifndef WORDS_BIGENDIAN
 # define WORDS_BIGENDIAN 0
 #endif
       if (!WORDS_BIGENDIAN)
+       {
        /* When host is little endian, we can just take a prefix of
           HARD_REG_SET, dropping any trailing unused 32-bit words.  On 64-bit
           hosts, compiling for the same target, we may get an extra half
           64-bit word due to the choice of a larger elts size, and that would
           affect hashing.  */
-       return iterative_hash (elts, n * t, 0);
+         if (test_hard_reg_set_hash)
+           goto second;
+         return iterative_hash (elts, n * t, 0);
+       }
       else
        {
+       second:
          const size_t m = HOST_BITS_PER_WIDEST_FAST_INT / s;
          const size_t l = ns * m - n;
          T normal[n];
@@ -275,6 +287,8 @@ allocno_hard_regs_hasher::hash (const allocno_hard_regs *hv)
                  T v = elt;
                  (elt >>= (s - 1)) >>= 1;
                  T w = bswp (v);
+                 if (!WORDS_BIGENDIAN)
+                   w = bswp (w);
                  normal[k] = w;
                }
              gcc_checking_assert (!elt);
@@ -290,6 +304,8 @@ allocno_hard_regs_hasher::hash (const allocno_hard_regs *hv)
                  T v = elt;
                  (elt >>= (s - 1)) >>= 1;
                  T w = bswp (v);
+                 if (!WORDS_BIGENDIAN)
+                   w = bswp (w);
                  normal[k] = w;
                }
              /* Negated sets may have left-overs half-words that are -1.  */
@@ -299,12 +315,18 @@ allocno_hard_regs_hasher::hash (const allocno_hard_regs 
*hv)
                                              << (l * s))
                                             >> (l * s)));
            }
-         gcc_checking_assert (k == n);
+         if (test_hard_reg_set_hash)
+           {
+             gcc_checking_assert (k == n);
+             gcc_checking_assert (memcmp (elts, normal, n * t) == 0);
+             goto third;
+           }
          return iterative_hash (normal, n * t, 0);
        }
     }
   else if ((HOST_BITS_PER_WIDEST_FAST_INT % 8) == 0)
     {
+    third:
       typedef unsigned char T;
       const size_t t = 1;
       const size_t s = t * 8;
@@ -349,10 +371,17 @@ allocno_hard_regs_hasher::hash (const allocno_hard_regs 
*hv)
                                         >> (l * s)));
        }
       gcc_checking_assert (k == n);
+      if (test_hard_reg_set_hash)
+       {
+         gcc_checking_assert (n * t == un * ut);
+         gcc_checking_assert (memcmp (elts, normal, n * t) == 0);
+         goto fourth;
+       }
       return iterative_hash (normal, n * t, 0);
     }
   else
     {
+    fourth:
       /* Cover unusual architectures.  */
       typedef unsigned char T;
       const size_t t = 1;
@@ -380,6 +409,11 @@ allocno_hard_regs_hasher::hash (const allocno_hard_regs 
*hv)
              normal[i/s] &= ~(1 << (i % s));
        }
       gcc_checking_assert (k == nb);
+      if (test_hard_reg_set_hash)
+       {
+         gcc_checking_assert (n * t == un * ut);
+         gcc_checking_assert (memcmp (elts, normal, n * t) == 0);
+       }
       return iterative_hash (normal, n * t, 0);
     }
 }

Reply via email to