aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-03-18 14:57:41 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2025-03-18 14:57:41 +0100
commitded45b72aaa43bbd8aa7c67f26a874cea8a18492 (patch)
tree1bea8efeb536cefd7a9f4e0d7177fb22e4acedaf
parent5c2c0155385d8a9ed23bf5d754481e7f945b9702 (diff)
downloadgcc-ded45b72aaa43bbd8aa7c67f26a874cea8a18492.zip
gcc-ded45b72aaa43bbd8aa7c67f26a874cea8a18492.tar.gz
gcc-ded45b72aaa43bbd8aa7c67f26a874cea8a18492.tar.bz2
lra: Handle SUBREG in lra_rtx_hash [PR119307]
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. 2025-03-18 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/119307 * lra.cc (lra_rtx_hash): Handle SUBREG. * gcc.target/i386/pr119307.c: New test.
-rw-r--r--gcc/lra.cc6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr119307.c14
2 files changed, 20 insertions, 0 deletions
diff --git a/gcc/lra.cc b/gcc/lra.cc
index 8f30284..8c69917 100644
--- a/gcc/lra.cc
+++ b/gcc/lra.cc
@@ -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;
}
diff --git a/gcc/testsuite/gcc.target/i386/pr119307.c b/gcc/testsuite/gcc.target/i386/pr119307.c
new file mode 100644
index 0000000..6b56f6b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr119307.c
@@ -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);
+}