https://gcc.gnu.org/g:3f1812fd97467bbc69c53169c663a9c4d26c1550

commit r16-8875-g3f1812fd97467bbc69c53169c663a9c4d26c1550
Author: H.J. Lu <[email protected]>
Date:   Mon May 4 05:08:51 2026 +0800

    or1k: Allow SImode for condition flag register
    
    Commit
    
    eb2ea476db2 emit-rtl: Allow extra checks for paradoxical subregs [PR119966]
    
    changed validate_subreg to return false on the paradoxical SImode subreg
    of the OpenRISC condition flag register (reg:BI sr_f), which triggered
    
    internal compiler error: in emit_move_multi_word, at expr.cc:4497
    
    c0694f95f59 or1k: Fix ICE in libgcc caused by recent validate_subreg changes
    
    changed or1k_can_change_mode_class to allow changing flags mode from BI
    to SI.  But or1k_hard_regno_mode_ok still returns false for condition
    flag register in SImode.  Update or1k_hard_regno_mode_ok to also allow
    condition flag register in SImode.
    
    Tested with or1k Linux cross compiler for or1k glibc build.
    
    gcc/
    
            PR target/120587
            PR target/125155
            * config/or1k/or1k.cc (or1k_hard_regno_mode_ok): Allow condition
            condition flag register in SImode.
    
    gcc/testsuite/
    
            PR target/120587
            PR target/125155
            * gcc.target/or1k/pr125155.c: New test.
    
    Signed-off-by: H.J. Lu <[email protected]>
    (cherry picked from commit 710581c80b2fd39fa7a8674eccf7dca8cbc7c9c0)

Diff:
---
 gcc/config/or1k/or1k.cc                  |  7 ++++---
 gcc/testsuite/gcc.target/or1k/pr125155.c | 14 ++++++++++++++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/gcc/config/or1k/or1k.cc b/gcc/config/or1k/or1k.cc
index 17240e3ee48d..66fd784f8b91 100644
--- a/gcc/config/or1k/or1k.cc
+++ b/gcc/config/or1k/or1k.cc
@@ -1389,10 +1389,11 @@ or1k_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain)
 static bool
 or1k_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
 {
-  /* For OpenRISC, GENERAL_REGS can hold anything, while
-     FLAG_REGS are really single bits within SP[SR].  */
+  /* For OpenRISC, GENERAL_REGS can hold anything, while FLAG_REGS are
+     really single bits within SP[SR].  Also allow condition flag register
+     in SImode to match or1k_can_change_mode_class.  */
   if (REGNO_REG_CLASS (regno) == FLAG_REGS)
-    return mode == BImode;
+    return mode == BImode || mode == SImode;
   return true;
 }
 
diff --git a/gcc/testsuite/gcc.target/or1k/pr125155.c 
b/gcc/testsuite/gcc.target/or1k/pr125155.c
new file mode 100644
index 000000000000..8ca95475b666
--- /dev/null
+++ b/gcc/testsuite/gcc.target/or1k/pr125155.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int __pthread_keys_0_0;
+int
+___pthread_key_delete (void)
+{
+  int result = 22;
+  int __atg3_old = 0;
+  if (__atomic_compare_exchange_n (&__pthread_keys_0_0, &__atg3_old,
+                                  0, 0, 2, 0))
+    result = 0;
+  return result;
+}

Reply via email to