https://gcc.gnu.org/g:9b55cd0405609474aab6fdd0c621fd738af5800a

commit r16-3252-g9b55cd0405609474aab6fdd0c621fd738af5800a
Author: Xi Ruoyao <xry...@xry111.site>
Date:   Sat Mar 1 11:46:45 2025 +0800

    LoongArch: Don't emit overly-restrictive barrier for LL-SC loops
    
    For LL-SC loops, if the atomic operation has succeeded, the SC
    instruction always imply a full barrier, so the barrier we manually
    inserted only needs to take the account for the failure memorder, not
    the success memorder (the barrier is skipped with "b 3f" on success
    anyway).
    
    Note that if we use the AMCAS instructions, we indeed need to consider
    both the success memorder an the failure memorder deciding if "_db"
    suffix is needed.  Thus the semantics of atomic_cas_value_strong<mode>
    and atomic_cas_value_strong<mode>_amcas start to be different.  To
    prevent the compiler from being too clever, use a different unspec code
    for AMCAS instructions.
    
    gcc/ChangeLog:
    
            * config/loongarch/sync.md (UNSPEC_COMPARE_AND_SWAP_AMCAS): New
            UNSPEC code.
            (atomic_cas_value_strong<mode>): NFC, update the comment to note
            we only need to consider failure memory order.
            (atomic_cas_value_strong<mode>_amcas): Use
            UNSPEC_COMPARE_AND_SWAP_AMCAS instead of
            UNSPEC_COMPARE_AND_SWAP.
            (atomic_compare_and_swap<mode:GPR>): Pass failure memorder to
            gen_atomic_cas_value_strong<mode>.
            (atomic_compare_and_swap<mode:SHORT>): Pass failure memorder to
            gen_atomic_cas_value_cmp_and_7_si.

Diff:
---
 gcc/config/loongarch/sync.md | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/gcc/config/loongarch/sync.md b/gcc/config/loongarch/sync.md
index 01346a79da22..5f894e573e97 100644
--- a/gcc/config/loongarch/sync.md
+++ b/gcc/config/loongarch/sync.md
@@ -21,6 +21,7 @@
 
 (define_c_enum "unspec" [
   UNSPEC_COMPARE_AND_SWAP
+  UNSPEC_COMPARE_AND_SWAP_AMCAS
   UNSPEC_COMPARE_AND_SWAP_ADD
   UNSPEC_COMPARE_AND_SWAP_SUB
   UNSPEC_COMPARE_AND_SWAP_AND
@@ -235,7 +236,7 @@
    (set (match_dup 1)
        (unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "rJ")
                              (match_operand:GPR 3 "reg_or_0_operand" "rJ")
-                             (match_operand:SI 4 "const_int_operand")]  ;; 
mod_s
+                             (match_operand:SI 4 "const_int_operand")]  ;; 
mod_f
         UNSPEC_COMPARE_AND_SWAP))
    (clobber (match_scratch:GPR 5 "=&r"))]
   ""
@@ -283,8 +284,8 @@
    (set (match_dup 1)
        (unspec_volatile:QHWD [(match_operand:QHWD 2 "reg_or_0_operand" "rJ")
                               (match_operand:QHWD 3 "reg_or_0_operand" "rJ")
-                              (match_operand:SI 4 "const_int_operand")]  ;; 
mod_s
-        UNSPEC_COMPARE_AND_SWAP))]
+                              (match_operand:SI 4 "const_int_operand")]  ;; mod
+        UNSPEC_COMPARE_AND_SWAP_AMCAS))]
   "ISA_HAS_LAMCAS"
   "ori\t%0,%z2,0\n\tamcas%A4.<size>\t%0,%z3,%1"
   [(set (attr "length") (const_int 8))])
@@ -313,16 +314,14 @@
       && is_mm_release (memmodel_base (INTVAL (mod_s))))
     mod_s = GEN_INT (MEMMODEL_ACQ_REL);
 
-  operands[6] = mod_s;
-
   if (ISA_HAS_LAMCAS)
     emit_insn (gen_atomic_cas_value_strong<mode>_amcas (operands[1], 
operands[2],
                                                         operands[3], 
operands[4],
-                                                        operands[6]));
+                                                        mod_s));
   else
     emit_insn (gen_atomic_cas_value_strong<mode> (operands[1], operands[2],
                                                  operands[3], operands[4],
-                                                 operands[6]));
+                                                 mod_f));
 
   rtx compare = operands[1];
   if (operands[3] != const0_rtx)
@@ -396,7 +395,7 @@
                              (match_operand:GPR 3 "reg_or_0_operand" "rJ")
                              (match_operand:GPR 4 "reg_or_0_operand"  "rJ")
                              (match_operand:GPR 5 "reg_or_0_operand"  "rJ")
-                             (match_operand:SI 6 "const_int_operand")] ;; model
+                             (match_operand:SI 6 "const_int_operand")] ;; mod_f
         UNSPEC_COMPARE_AND_SWAP))
    (clobber (match_scratch:GPR 7 "=&r"))]
   ""
@@ -440,18 +439,16 @@
       && is_mm_release (memmodel_base (INTVAL (mod_s))))
     mod_s = GEN_INT (MEMMODEL_ACQ_REL);
 
-  operands[6] = mod_s;
-
   if (ISA_HAS_LAMCAS)
     emit_insn (gen_atomic_cas_value_strong<mode>_amcas (operands[1], 
operands[2],
                                                       operands[3], operands[4],
-                                                      operands[6]));
+                                                      mod_s));
   else
     {
       union loongarch_gen_fn_ptrs generator;
       generator.fn_7 = gen_atomic_cas_value_cmp_and_7_si;
       loongarch_expand_atomic_qihi (generator, operands[1], operands[2],
-                                   operands[3], operands[4], operands[6]);
+                                   operands[3], operands[4], mod_f);
     }
 
       rtx compare = operands[1];

Reply via email to