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); } }
