Hi! The following testcase ICEs starting with r15-3213 in decompose_normal_address and starting with r15-3288 ICEs in lra_rtx_hash, which since r8-5466 can't handle SUBREG (previously SUBREG was "ei" and lra_rtx_hash can handle that through val += lra_rtx_hash (XEXP (x, i)); for e and val += XINT (x, i); for i, now it is "ep" where p stands for poly_uint16).
The following patch fixes it by handling SUBREG directly, a variant could be instead add case 'p': for (int i = 0; i < NUM_POLY_INT_COEFFS; ++i) val += SUBREG_BYTE (x).coeffs[i]; break; if you prefer that more (p is used solely for SUBREG and e.g. rtx_equal_p has case 'p': if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y))) return false; break; ). Given the above rtx_equal_p snippet and that lra_rtx_hash is solely used in invariant_hash (and recursion) and invariant_eq_p uses rtx_equal_p we'll never consider different SUBREGs of the same thing as the same invariant. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk or do you prefer the case 'p' variant mentioned above? 2025-03-18 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/119307 * lra.cc (lra_rtx_hash): Handle SUBREG. * gcc.target/i386/pr119307.c: New test. --- gcc/lra.cc.jj 2025-02-26 19:24:53.408264023 +0100 +++ gcc/lra.cc 2025-03-17 10:07:24.299064598 +0100 @@ -1730,6 +1730,12 @@ lra_rtx_hash (rtx x) case CONST_INT: return val + UINTVAL (x); + case SUBREG: + val += lra_rtx_hash (SUBREG_REG (x)); + for (int i = 0; i < NUM_POLY_INT_COEFFS; ++i) + val += SUBREG_BYTE (x).coeffs[i]; + return val; + default: break; } --- gcc/testsuite/gcc.target/i386/pr119307.c.jj 2025-03-17 10:19:11.546152504 +0100 +++ gcc/testsuite/gcc.target/i386/pr119307.c 2025-03-17 10:18:49.372463269 +0100 @@ -0,0 +1,14 @@ +/* PR rtl-optimization/119307 */ +/* { dg-do compile { target x32 } } */ +/* { dg-require-profiling "-fprofile-generate" } */ +/* { dg-options "-Os -maddress-mode=long -fprofile-generate -ftrapv" } */ + +_Complex int x; +__int128 y; +long n; + +void +foo (void) +{ + x *= *(__int128 *) __builtin_memmove (&y, &x, n); +} Jakub