https://gcc.gnu.org/g:ded45b72aaa43bbd8aa7c67f26a874cea8a18492

commit r15-8253-gded45b72aaa43bbd8aa7c67f26a874cea8a18492
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Mar 18 14:57:41 2025 +0100

    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  <ja...@redhat.com>
    
            PR rtl-optimization/119307
            * lra.cc (lra_rtx_hash): Handle SUBREG.
    
            * gcc.target/i386/pr119307.c: New test.

Diff:
---
 gcc/lra.cc                               |  6 ++++++
 gcc/testsuite/gcc.target/i386/pr119307.c | 14 ++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/gcc/lra.cc b/gcc/lra.cc
index 8f30284e9daa..8c6991751e5c 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 000000000000..6b56f6b0ec1c
--- /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);
+}

Reply via email to