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

commit r17-3230-gd9e21f7c4d1666baec96398f07ac500d1c912a12
Author: H.J. Lu <[email protected]>
Date:   Fri Jul 17 08:35:34 2026 +0800

    x86-64: Add -m128bit-atomic
    
    With the silicon vendor guarantees from Intel, AMD, Hygon and Zhaoxin in:
    
    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104688
    
    many software developers would happily use inline 128-bit atomic loads
    and stores in their programs because they only target compatible CPUs.
    Add -m128bit-atomic to generate 128-bit atomic loads and stores to avoid
    the overhead of calling into libatomic.  Enable -m128bit-atomic in 64-bit
    mode by default if supported by the targeting processor, which is one of
    x86-64-v3 capable processors as well as AVX capable processors from Intel,
    AMD, Hygon and Zhaoxin.
    
    gcc/
    
            PR target/94649
            PR target/126293
            * common/config/i386/i386-cpuinfo.h (ix86_decode_cpu_info): New
            function.
            * config/i386/i386-options.cc
            (ix86_option_override_internal): Issue an error for -m128bit-atomic
            in 32-bit mode.  Turn on -mcx16 if -m128bit-atomic is enabled.
            Enable -m128bit-atomic in 64-bit mode by default if supported by
            the targeting processor.
            * config/i386/i386.h (TARGET_128BIT_ATOMIC_ENABLED): New.
            * config/i386/i386.opt (m128bit-atomic): New option.
            * config/i386/i386.opt.urls: Regenerated.
            * config/i386/sync.md: Update comments for 128-bit aligned vector
            loads and stores.
            (atomic_loadti): New pattern.
            (atomic_loadti_sse): Likewise.
            (atomic_storeti): Likewise.
            (atomic_storeti_sse): Likewise.
            * doc/invoke.texi: Remove __atomic Builtins reference from -mcx16.
            Document -m128bit-atomic.
    
    gcc/testsuite/
    
            PR target/94649
            PR target/126293
            * g++.target/i386/pr94649-1.C: New test.
            * gcc.target/i386/pr126293-1a.c: Likewise.
            * gcc.target/i386/pr126293-1b.c: Likewise.
            * gcc.target/i386/pr126293-1c.c: Likewise.
            * gcc.target/i386/pr126293-1d.c: Likewise.
            * gcc.target/i386/pr126293-2a.c: Likewise.
            * gcc.target/i386/pr126293-2b.c: Likewise.
            * gcc.target/i386/pr126293-3a.c: Likewise.
            * gcc.target/i386/pr126293-3b.c: Likewise.
            * gcc.target/i386/pr126293-4a.c: Likewise.
            * gcc.target/i386/pr126293-4b.c: Likewise.
            * gcc.target/i386/pr126293-4c.c: Likewise.
            * gcc.target/i386/pr126293-4d.c: Likewise.
            * gcc.target/i386/pr126293-4e.c: Likewise.
            * gcc.target/i386/pr126293-4f.c: Likewise.
            * gcc.target/i386/pr126293-4g.c: Likewise.
            * gcc.target/i386/pr126293-4h.c: Likewise.
            * gcc.target/i386/pr126293-4i.c: Likewise.
            * gcc.target/i386/pr126293-4j.c: Likewise.
            * gcc.target/i386/pr126293-4k.c: Likewise.
            * gcc.target/i386/pr126293-4l.c: Likewise.
            * gcc.target/i386/pr126293-4m.c: Likewise.
            * gcc.target/i386/pr126293-4n.c: Likewise.
            * gcc.target/i386/pr126293-4o.c: Likewise.
            * gcc.target/i386/pr126293-4p.c: Likewise.
            * gcc.target/i386/pr126293-4q.c: Likewise.
            * gcc.target/i386/pr126293-4r.c: Likewise.
            * gcc.target/i386/pr126293-4s.c: Likewise.
            * gcc.target/i386/pr126293-5.c: Likewise.
            * gcc.target/i386/pr126293-6.c: Likewise.
            * gcc.target/i386/pr126293-7.c: Likewise.
            * gcc.target/i386/pr126293-8.c: Likewise.
            * gcc.target/i386/pr126293-9.c: Likewise.
            * gcc.target/i386/pr126293-10.c: Likewise.
            * gcc.target/i386/pr126293-11.c: Likewise.
            * gcc.target/i386/pr126293-12.c: Likewise.
            * gcc.target/i386/pr126293-13.c: Likewise.
            * gcc.target/i386/pr126293-14.c: Likewise.
            * gcc.target/i386/pr126293-15.c: Likewise.
            * gcc.target/i386/pr126293-16.c: Likewise.
            * gcc.target/i386/pr126293-17.c: Likewise.
    
    Signed-off-by: H.J. Lu <[email protected]>

Diff:
---
 gcc/common/config/i386/i386-cpuinfo.h       | 126 ++++++++++++++++++++++++++++
 gcc/config/i386/i386-options.cc             |  50 +++++++++++
 gcc/config/i386/i386.h                      |   9 ++
 gcc/config/i386/i386.opt                    |   4 +
 gcc/config/i386/i386.opt.urls               |   3 +
 gcc/config/i386/sync.md                     |  60 ++++++++++++-
 gcc/doc/invoke.texi                         |  24 +++++-
 gcc/testsuite/g++.target/i386/pr94649-1.C   |  17 ++++
 gcc/testsuite/gcc.target/i386/pr126293-10.c |  26 ++++++
 gcc/testsuite/gcc.target/i386/pr126293-11.c |  24 ++++++
 gcc/testsuite/gcc.target/i386/pr126293-12.c |  29 +++++++
 gcc/testsuite/gcc.target/i386/pr126293-13.c |  28 +++++++
 gcc/testsuite/gcc.target/i386/pr126293-14.c |  31 +++++++
 gcc/testsuite/gcc.target/i386/pr126293-15.c |  30 +++++++
 gcc/testsuite/gcc.target/i386/pr126293-16.c |   3 +
 gcc/testsuite/gcc.target/i386/pr126293-17.c |   4 +
 gcc/testsuite/gcc.target/i386/pr126293-1a.c |  22 +++++
 gcc/testsuite/gcc.target/i386/pr126293-1b.c |   6 ++
 gcc/testsuite/gcc.target/i386/pr126293-1c.c |   6 ++
 gcc/testsuite/gcc.target/i386/pr126293-1d.c |   6 ++
 gcc/testsuite/gcc.target/i386/pr126293-2a.c |  23 +++++
 gcc/testsuite/gcc.target/i386/pr126293-2b.c |  55 ++++++++++++
 gcc/testsuite/gcc.target/i386/pr126293-3a.c |  21 +++++
 gcc/testsuite/gcc.target/i386/pr126293-3b.c |  45 ++++++++++
 gcc/testsuite/gcc.target/i386/pr126293-4a.c |  31 +++++++
 gcc/testsuite/gcc.target/i386/pr126293-4b.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4c.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4d.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4e.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4f.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4g.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4h.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4i.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4j.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4k.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4l.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4m.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4n.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4o.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4p.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4q.c |  19 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4r.c |  20 +++++
 gcc/testsuite/gcc.target/i386/pr126293-4s.c |  20 +++++
 gcc/testsuite/gcc.target/i386/pr126293-5.c  |  25 ++++++
 gcc/testsuite/gcc.target/i386/pr126293-6.c  |  24 ++++++
 gcc/testsuite/gcc.target/i386/pr126293-7.c  |  23 +++++
 gcc/testsuite/gcc.target/i386/pr126293-8.c  |  24 ++++++
 gcc/testsuite/gcc.target/i386/pr126293-9.c  |  23 +++++
 48 files changed, 1140 insertions(+), 6 deletions(-)

diff --git a/gcc/common/config/i386/i386-cpuinfo.h 
b/gcc/common/config/i386/i386-cpuinfo.h
index 5b9bf5db68b3..dd3b4e46d8b8 100644
--- a/gcc/common/config/i386/i386-cpuinfo.h
+++ b/gcc/common/config/i386/i386-cpuinfo.h
@@ -300,3 +300,129 @@ enum processor_features
 #define M_VENDOR(a) (a)
 #define M_CPU_TYPE(a) (M_CPU_TYPE_START + int (a))
 #define M_CPU_SUBTYPE(a) (M_CPU_SUBTYPE_START + a)
+
+#ifdef __cplusplus
+/* Extract processor VENDOR, TYPE and SUBTYPE from MODEL.  */
+
+static inline void
+ix86_decode_cpu_info (int model, processor_vendor &vendor,
+                     processor_types &type,
+                     processor_subtypes &subtype)
+{
+  if (model > M_CPU_SUBTYPE_START)
+    {
+      subtype = (processor_subtypes) (model - M_CPU_SUBTYPE_START);
+      if (subtype <= INTEL_COREI7_SANDYBRIDGE
+         || (subtype >= INTEL_COREI7_IVYBRIDGE
+             && subtype <= INTEL_COREI7_ICELAKE_SERVER)
+         || (subtype >= INTEL_COREI7_CASCADELAKE
+             && subtype <= INTEL_COREI7_ALDERLAKE)
+         || subtype == INTEL_COREI7_ROCKETLAKE
+         || (subtype >= INTEL_COREI7_GRANITERAPIDS
+             && subtype <= INTEL_COREI7_PANTHERLAKE)
+         || subtype == INTEL_COREI7_DIAMONDRAPIDS
+         || subtype == INTEL_COREI7_NOVALAKE)
+       {
+         vendor = VENDOR_INTEL;
+         type = INTEL_COREI7;
+       }
+      else if (subtype >= AMDFAM10H_BARCELONA
+              && subtype <= AMDFAM10H_ISTANBUL)
+       {
+         vendor = VENDOR_AMD;
+         type = AMDFAM10H;
+       }
+      else if (subtype >= AMDFAM15H_BDVER1
+              && subtype <= AMDFAM15H_BDVER4)
+       {
+         vendor = VENDOR_AMD;
+         type = AMDFAM15H;
+       }
+      else if (subtype == AMDFAM17H_ZNVER1
+              || subtype == AMDFAM17H_ZNVER2)
+       {
+         vendor = VENDOR_AMD;
+         type = AMDFAM17H;
+       }
+      else if (subtype == AMDFAM19H_ZNVER3
+              || subtype == AMDFAM19H_ZNVER4)
+       {
+         vendor = VENDOR_AMD;
+         type = AMDFAM19H;
+       }
+      else if (subtype == AMDFAM1AH_ZNVER5
+              || subtype == AMDFAM1AH_ZNVER6)
+       {
+         vendor = VENDOR_AMD;
+         type = AMDFAM1AH;
+       }
+      else if (subtype == ZHAOXIN_FAM7H_LUJIAZUI
+              || subtype == ZHAOXIN_FAM7H_YONGFENG
+              || subtype == ZHAOXIN_FAM7H_SHIJIDADAO)
+       {
+         vendor = VENDOR_ZHAOXIN;
+         type = ZHAOXIN_FAM7H;
+       }
+      else if (subtype >= HYGONFAM18H_C86_4G_M4
+              && subtype <= HYGONFAM18H_C86_4G_M8)
+       {
+         vendor = VENDOR_HYGON;
+         type = HYGONFAM18H;
+       }
+      else
+       {
+         /* Set VENDOR to VENDOR_OTHER and TYPE to CPU_TYPE_MAX for
+            unsupported SUBTYPE.  */
+         vendor = VENDOR_OTHER;
+         type = CPU_TYPE_MAX;
+       }
+    }
+  else if (model > M_CPU_TYPE_START)
+    {
+      type = (processor_types) (model - M_CPU_TYPE_START);
+      if ((type >= INTEL_BONNELL && type <= INTEL_COREI7)
+         || type == INTEL_SILVERMONT
+         || (type >= INTEL_GOLDMONT && type <= INTEL_TREMONT)
+         || (type >= INTEL_SIERRAFOREST
+             && type <= INTEL_CLEARWATERFOREST))
+       {
+         vendor = VENDOR_INTEL;
+         subtype = CPU_SUBTYPE_MAX;
+       }
+      else if (type == AMDFAM10H
+              || type == AMDFAM15H
+              || (type >= AMD_BTVER1 && type <= AMDFAM17H)
+              || type == AMDFAM19H
+              || type == AMDFAM1AH)
+       {
+         vendor = VENDOR_AMD;
+         subtype = CPU_SUBTYPE_MAX;
+       }
+      else if (type == ZHAOXIN_FAM7H)
+       {
+         vendor = VENDOR_ZHAOXIN;
+         subtype = CPU_SUBTYPE_MAX;
+       }
+      else if (type == HYGONFAM18H)
+       {
+         vendor = VENDOR_HYGON;
+         subtype = CPU_SUBTYPE_MAX;
+       }
+      else
+       {
+         /* Set VENDOR to VENDOR_OTHER and SUBTYPE to CPU_SUBTYPE_MAX
+            for unsupported TYPE.  */
+         vendor = VENDOR_OTHER;
+         subtype = CPU_SUBTYPE_MAX;
+       }
+    }
+  else
+    {
+      vendor = (processor_vendor) model;
+      /* Set TYPE to CPU_TYPE_MAX and SUBTYPE to CPU_SUBTYPE_MAX for
+        unknown TYPE and SUBTYPE.  */
+      type = CPU_TYPE_MAX;
+      subtype = CPU_SUBTYPE_MAX;
+    }
+}
+#endif
diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
index afbd96b79c33..6bb5e1a08d9a 100644
--- a/gcc/config/i386/i386-options.cc
+++ b/gcc/config/i386/i386-options.cc
@@ -2305,6 +2305,11 @@ ix86_option_override_internal (bool main_args_p,
     sorry ("%i-bit mode not compiled in",
           (opts->x_ix86_isa_flags & OPTION_MASK_ISA_64BIT) ? 64 : 32);
 
+  processor_vendor ix86_vendor = VENDOR_OTHER;
+  processor_types ix86_type = CPU_TYPE_MAX;
+  processor_subtypes ix86_subtype = CPU_SUBTYPE_MAX;
+  wide_int_bitmask ix86_pta = 0;
+
   /* Last processor_alias_table must point to "generic" entry.  */
   gcc_checking_assert (strcmp (processor_alias_table[pta_size - 1].name,
                               "generic") == 0);
@@ -2340,6 +2345,10 @@ ix86_option_override_internal (bool main_args_p,
 
        ix86_schedule = processor_alias_table[i].schedule;
        ix86_arch = processor_alias_table[i].processor;
+       ix86_pta = processor_alias_table[i].flags;
+
+       ix86_decode_cpu_info (processor_alias_table[i].model,
+                             ix86_vendor, ix86_type, ix86_subtype);
 
        /* Default cpu tuning to the architecture, unless the table
           entry requests not to do this.  Used by the x86-64 psABI
@@ -2528,6 +2537,47 @@ ix86_option_override_internal (bool main_args_p,
       XDELETEVEC (s);
     }
 
+  /* Disable -m128bit-atomic if not set on command-line.  */
+  if (!TARGET_128BIT_ATOMIC_P (opts_set->x_ix86_target_flags))
+    opts->x_ix86_target_flags &= ~OPTION_MASK_128BIT_ATOMIC;
+
+  if (TARGET_128BIT_ATOMIC_P (opts->x_ix86_target_flags))
+    {
+      if (!TARGET_64BIT_P (opts->x_ix86_isa_flags))
+       error ("%<-m128bit-atomic%> not supported for 32-bit code");
+      else if (!TARGET_CX16_P (opts_set->x_ix86_isa_flags2))
+       {
+         /* Enable CMPXCHG16B when -m128bit-atomic is enabled.  */
+         opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_CX16;
+       }
+    }
+  else if (!TARGET_128BIT_ATOMIC_P (opts_set->x_ix86_target_flags)
+          && TARGET_64BIT_P (opts->x_ix86_isa_flags)
+          && ((TARGET_AVX_P (opts->x_ix86_isa_flags)
+               && (ix86_vendor == VENDOR_INTEL
+                   || ix86_vendor == VENDOR_AMD
+                   || ix86_vendor == VENDOR_HYGON
+                   || ix86_vendor == VENDOR_ZHAOXIN))
+              || (ix86_pta & PTA_X86_64_V3) == PTA_X86_64_V3
+              || ix86_type == AMDFAM17H
+              || ix86_type == AMDFAM19H
+              || ix86_type == AMDFAM1AH
+              || ix86_type == HYGONFAM18H
+              || (ix86_type >= INTEL_SIERRAFOREST
+                  && ix86_type <= INTEL_CLEARWATERFOREST)
+              || ix86_subtype == INTEL_COREI7_SANDYBRIDGE
+              || (ix86_subtype >= AMDFAM17H_ZNVER1
+                  && ix86_subtype <= INTEL_COREI7_ROCKETLAKE)
+              || (ix86_subtype >= AMDFAM19H_ZNVER4
+                  && ix86_subtype <= HYGONFAM18H_C86_4G_M8)))
+    {
+      /* Turn on -m128bit-atomic in 64-bit mode by default if supported
+        by the targeting processor, which is one of x86-64-v3 capable
+        processors as well as AVX capable processors from Intel, AMD,
+        Hygon and Zhaoxin.  */
+      opts->x_ix86_target_flags |= OPTION_MASK_128BIT_ATOMIC;
+    }
+
   set_ix86_tune_features (opts, ix86_tune, opts->x_ix86_dump_tunes);
 
   ix86_recompute_optlev_based_flags (opts, opts_set);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index d4082a840593..26c3b73a50f9 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -3085,6 +3085,15 @@ extern void debug_dispatch_window (int);
 #define TARGET_RECIP_VEC_DIV   ((recip_mask & RECIP_MASK_VEC_DIV) != 0)
 #define TARGET_RECIP_VEC_SQRT  ((recip_mask & RECIP_MASK_VEC_SQRT) != 0)
 
+/* -m128bit-atomic requires CMPXCHG16B and SSE2.
+
+   Note: Pre-Tiger Lake (Desktop/Mobile): Generations including Kaby
+   Lake, Coffee Lake, and Comet Lake (e.g., Pentium Gold G5400, Celeron
+   G5900, N4020) do not support AVX.  However, 128-bit aligned SSE loads
+   and stores are atomic on these processors.  Should AVX be required?  */
+#define TARGET_128BIT_ATOMIC_ENABLED \
+  (TARGET_CX16 && TARGET_SSE2 && TARGET_128BIT_ATOMIC)
+
 /* Use 128-bit AVX instructions in the auto-vectorizer.  */
 #define TARGET_PREFER_AVX128   (prefer_vector_width_type == PVW_AVX128)
 /* Use 256-bit AVX instructions in the auto-vectorizer.  */
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 2cdc71a2324e..57ba3fbfa8f1 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1043,6 +1043,10 @@ mgeneral-regs-only
 Target RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save
 Generate code which uses only the general registers.
 
+m128bit-atomic
+Target Mask(128BIT_ATOMIC) Var(ix86_target_flags) Save
+Generate cmpxchg16b, 128-bit atomic vector loads and stores for the x86-64 
architecture.
+
 mshstk
 Target Mask(ISA_SHSTK) Var(ix86_isa_flags) Save
 Enable shadow stack built-in functions from Control-flow Enforcement
diff --git a/gcc/config/i386/i386.opt.urls b/gcc/config/i386/i386.opt.urls
index d0c58ca35267..d52e6de80146 100644
--- a/gcc/config/i386/i386.opt.urls
+++ b/gcc/config/i386/i386.opt.urls
@@ -464,6 +464,9 @@ 
UrlSuffix(gcc/x86-Options.html#index-mstack-protector-guard-symbol)
 mgeneral-regs-only
 UrlSuffix(gcc/x86-Options.html#index-mgeneral-regs-only-2)
 
+m128bit-atomic
+UrlSuffix(gcc/x86-Options.html#index-m128bit-atomic)
+
 mshstk
 UrlSuffix(gcc/x86-Options.html#index-mshstk)
 
diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md
index d9f822f48218..19bf1757aeef 100644
--- a/gcc/config/i386/sync.md
+++ b/gcc/config/i386/sync.md
@@ -150,9 +150,8 @@
 ;;
 ;; Note that the TARGET_CMPXCHG8B test below is a stand-in for "Pentium".
 ;;
-;; Importantly, *no* processor makes atomicity guarantees for larger
-;; accesses.  In particular, there's no way to perform an atomic TImode
-;; move, despite the apparent applicability of MOVDQA et al.
+;; AVX capable processors from Intel, AMD, Hygon and Zhaoxin guarantee
+;; that 128-bit aligned vector loads and stores are atomic.
 
 (define_mode_iterator ATOMIC
    [QI HI SI
@@ -388,6 +387,61 @@
   [(set_attr "type" "ssemov")
    (set_attr "mode" "DI")])
 
+(define_expand "atomic_loadti"
+  [(set (match_operand:TI 0 "register_operand")
+     (unspec:TI [(match_operand:TI 1 "memory_operand")
+                 (match_operand:SI 2 "const_int_operand")]
+                UNSPEC_LDA))]
+  "TARGET_128BIT_ATOMIC_ENABLED"
+{
+  emit_insn (gen_atomic_loadti_sse (operands[0], operands[1]));
+  DONE;
+})
+
+(define_insn_and_split "atomic_loadti_sse"
+  [(set (match_operand:TI 0 "register_operand" "=v")
+     (unspec:TI [(match_operand:TI 1 "memory_operand" "m")]
+                UNSPEC_LDX_ATOMIC))]
+  "TARGET_128BIT_ATOMIC_ENABLED"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (match_dup 1))])
+
+(define_expand "atomic_storeti"
+  [(set (match_operand:TI 0 "memory_operand")
+     (unspec:TI [(match_operand:TI 1 "nonimmediate_operand")
+                 (match_operand:SI 2 "const_int_operand")]
+                UNSPEC_STA))]
+  "TARGET_128BIT_ATOMIC_ENABLED"
+{
+  enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
+
+  /* Use V1TImode to force vector register for atomic store.  */
+  rtx src = gen_reg_rtx (V1TImode);
+  rtx op1 = gen_lowpart (V1TImode, operands[1]);
+  emit_move_insn (src, op1);
+  emit_insn (gen_atomic_storeti_sse (operands[0], src));
+
+  /* ... followed by an MFENCE, if required.  */
+  if (is_mm_seq_cst (model))
+    emit_insn (gen_mem_thread_fence (operands[2]));
+  DONE;
+})
+
+(define_insn_and_split "atomic_storeti_sse"
+  [(set (match_operand:TI 0 "memory_operand" "=m")
+     (unspec:TI [(match_operand:V1TI 1 "nonimmediate_operand" "v")]
+                UNSPEC_STX_ATOMIC))]
+  "TARGET_128BIT_ATOMIC_ENABLED"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+{
+  rtx src = gen_lowpart (TImode, operands[1]);
+  emit_move_insn (operands[0], src);
+  DONE;
+})
+
 (define_expand "atomic_compare_and_swap<mode>"
   [(match_operand:QI 0 "register_operand")     ;; bool success output
    (match_operand:SWI124 1 "register_operand") ;; oldval output
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 7c65c9242716..2e53a8c8a7ee 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1576,7 +1576,7 @@ See RS/6000 and PowerPC Options.
 -mstack-protector-guard-offset=@var{offset}
 -mstack-protector-guard-symbol=@var{symbol}
 -mgeneral-regs-only  -mcall-ms2sysv-xlogues  -mtls-dialect=@var{type}
--mrelax-cmpxchg-loop
+-m128bit-atomic -mrelax-cmpxchg-loop
 -mindirect-branch=@var{choice}  -mfunction-return=@var{choice}
 -mindirect-branch-register  -mharden-sls=@var{choice}
 -mindirect-branch-cs-prefix  -mapx-inline-asm-use-gpr32
@@ -36726,8 +36726,7 @@ This option enables GCC to generate @code{CMPXCHG16B} 
instructions in 64-bit
 code to implement compare-and-exchange operations on 16-byte aligned 128-bit
 objects.  This is useful for atomic updates of data structures exceeding one
 machine word in size.  The compiler uses this instruction to implement
-@ref{__sync Builtins}.  However, for @ref{__atomic Builtins} operating on
-128-bit integers, a library call is always used.
+@ref{__sync Builtins}.
 
 @opindex msahf
 @opindex mno-sahf
@@ -37292,6 +37291,25 @@ Generate code that uses only the general-purpose 
registers.  This
 prevents the compiler from using floating-point, vector, mask and bound
 registers.
 
+@opindex m128bit-atomic
+@opindex mno-128bit-atomic
+@item -m128bit-atomic
+Generate cmpxchg16b, 128-bit atomic vector load and store instructions
+for the x86-64 architecture.  This is safe to use only on x86-64-v3
+capable processors as well as AVX capable processors from Intel, AMD,
+Hygon and Zhaoxin, which guarantee that 128-bit aligned vector loads
+and stores are atomic.  This option requires SSE2 and CMPXCHG16B.  It
+implies @option{-mcx16} which enables CMPXCHG16B.  This option is
+enabled in 64-bit mode by default if supported by the targeting
+processor.  For @ref{__atomic Builtins} operating on 128-bit integers,
+this option generates atomic instructions directly, instead of calling
+a library function in the @file{libatomic} runtime library.
+
+Note that when SSE2 is disabled, i.e., by @option{-mgeneral-regs-only},
+128-bit atomic operations are unsupported and @file{libatomic} shouldn't
+be used since it may use SSE2 or AVX instructions to implement 128-bit
+atomic operations.
+
 @opindex mrelax-cmpxchg-loop
 @opindex mno-relax-cmpxchg-loop
 @item -mrelax-cmpxchg-loop
diff --git a/gcc/testsuite/g++.target/i386/pr94649-1.C 
b/gcc/testsuite/g++.target/i386/pr94649-1.C
new file mode 100644
index 000000000000..7871e319134c
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr94649-1.C
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -std=c++11 -march=x86-64 -m128bit-atomic" } */
+/* { dg-final { scan-assembler-times "lock;?\[ \\t\]+cmpxchg16b" 1 } } */
+
+#include <atomic>
+
+struct alignas(16) a
+{
+  long x;
+  long y;
+};
+
+bool
+cmpxchg(std::atomic<a>& data, a expected, a newval)
+{
+  return std::atomic_compare_exchange_weak(&data, &expected, newval);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-10.c 
b/gcc/testsuite/gcc.target/i386/pr126293-10.c
new file mode 100644
index 000000000000..462042c29bb1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-10.c
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     fldt    8\(%rsp\)
+**     fstpt   -24\(%rsp\)
+**     movdqa  -24\(%rsp\), %xmm0
+**     movaps  %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+extern _Atomic long double store;
+
+void
+func (long double i)
+{
+  store = i;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-11.c 
b/gcc/testsuite/gcc.target/i386/pr126293-11.c
new file mode 100644
index 000000000000..aa65acda009a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-11.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movdqa  load\(%rip\), %xmm0
+**     movaps  %xmm0, -24\(%rsp\)
+**     fldt    -24\(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+extern _Atomic long double load;
+
+long double
+func (void)
+{
+  return load;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-12.c 
b/gcc/testsuite/gcc.target/i386/pr126293-12.c
new file mode 100644
index 000000000000..065b779c4093
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-12.c
@@ -0,0 +1,29 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movaps  %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+typedef float vector __attribute__((vector_size (16)));
+typedef struct
+{
+  vector v;
+} v;
+
+extern _Atomic v store;
+
+void
+func (v i)
+{
+  store = i;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-13.c 
b/gcc/testsuite/gcc.target/i386/pr126293-13.c
new file mode 100644
index 000000000000..a46eb736347b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-13.c
@@ -0,0 +1,28 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movdqa  load\(%rip\), %xmm0
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+typedef float vector __attribute__((vector_size (16)));
+typedef struct
+{
+  vector v;
+} v;
+
+extern _Atomic v load;
+
+v
+func (void)
+{
+  return load;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-14.c 
b/gcc/testsuite/gcc.target/i386/pr126293-14.c
new file mode 100644
index 000000000000..14d9822b4768
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-14.c
@@ -0,0 +1,31 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movq    %rdi, %xmm0
+**     movq    %rsi, %xmm1
+**     punpcklqdq      %xmm1, %xmm0
+**     movaps  %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+typedef struct
+{
+  int a[4];
+} s;
+
+extern _Atomic s store;
+
+void
+func (s i)
+{
+  store = i;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-15.c 
b/gcc/testsuite/gcc.target/i386/pr126293-15.c
new file mode 100644
index 000000000000..058e432058d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-15.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movdqa  load\(%rip\), %xmm0
+**     movaps  %xmm0, -24\(%rsp\)
+**     movq    -24\(%rsp\), %rax
+**     movq    -16\(%rsp\), %rdx
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+typedef struct
+{
+  int a[4];
+} s;
+
+_Atomic s load;
+
+s
+func (void)
+{
+  return load;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-16.c 
b/gcc/testsuite/gcc.target/i386/pr126293-16.c
new file mode 100644
index 000000000000..4c4d486bc304
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-16.c
@@ -0,0 +1,3 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-additional-options "-O2 -march=x86-64 -m128bit-atomic" } */
+/* { dg-error "'-m128bit-atomic' not supported for 32-bit code" "" { target 
*-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-17.c 
b/gcc/testsuite/gcc.target/i386/pr126293-17.c
new file mode 100644
index 000000000000..aafee4797fb8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-17.c
@@ -0,0 +1,4 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-additional-options "-O2 -march=x86-64-v3" } */
+
+#include <x86intrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-1a.c 
b/gcc/testsuite/gcc.target/i386/pr126293-1a.c
new file mode 100644
index 000000000000..cd34926a377f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-1a.c
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -march=x86-64 -m128bit-atomic" } */
+/* { dg-final { scan-assembler-times "lock;?\[ \\t\]+cmpxchg16b" 8 } } */
+
+#include <stdint.h>
+
+#define FUNC_ATOMIC(TYPE, OP) \
+__attribute__ ((noinline, noclone))    \
+TYPE f_##TYPE##_##OP##_fetch (TYPE *a, TYPE b) \
+{ \
+  return __atomic_##OP##_fetch (a, b, __ATOMIC_RELAXED);  \
+} \
+__attribute__ ((noinline, noclone))    \
+TYPE f_##TYPE##_fetch_##OP (TYPE *a, TYPE b)   \
+{ \
+  return __atomic_fetch_##OP (a, b, __ATOMIC_RELAXED);  \
+}
+
+FUNC_ATOMIC (__int128_t, and)
+FUNC_ATOMIC (__int128_t, nand)
+FUNC_ATOMIC (__int128_t, or)
+FUNC_ATOMIC (__int128_t, xor)
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-1b.c 
b/gcc/testsuite/gcc.target/i386/pr126293-1b.c
new file mode 100644
index 000000000000..bbd74e4c73ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-1b.c
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -march=x86-64 -mno-cx16 -m128bit-atomic" } */
+/* { dg-final { scan-assembler-times "call\[ \\t\]+__atomic_fetch_" 4 } } */
+/* { dg-final { scan-assembler-times "jmp\[ \\t\]+__atomic_fetch_" 4 } } */
+
+#include "pr126293-1a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-1c.c 
b/gcc/testsuite/gcc.target/i386/pr126293-1c.c
new file mode 100644
index 000000000000..85fe25cae8b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-1c.c
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -march=x86-64 -m128bit-atomic -mno-cx16" } */
+/* { dg-final { scan-assembler-times "call\[ \\t\]+__atomic_fetch_" 4 } } */
+/* { dg-final { scan-assembler-times "jmp\[ \\t\]+__atomic_fetch_" 4 } } */
+
+#include "pr126293-1a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-1d.c 
b/gcc/testsuite/gcc.target/i386/pr126293-1d.c
new file mode 100644
index 000000000000..6ca19cb10609
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-1d.c
@@ -0,0 +1,6 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -march=x86-64 -m128bit-atomic" } */
+/* { dg-final { scan-assembler-times "lock;?\[ \\t\]+cmpxchg16b" 8 } } */
+
+#include <x86intrin.h>
+#include "pr126293-1a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-2a.c 
b/gcc/testsuite/gcc.target/i386/pr126293-2a.c
new file mode 100644
index 000000000000..d2a11579d2fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-2a.c
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -march=x86-64 -m128bit-atomic 
-mrelax-cmpxchg-loop" } */
+/* { dg-final { scan-assembler-times "rep;?\[ \\t\]+nop" 8 } } */
+/* { dg-final { scan-assembler-times "lock;?\[ \\t\]+cmpxchg16b" 8 } } */
+
+#include <stdint.h>
+
+#define FUNC_ATOMIC(TYPE, OP) \
+__attribute__ ((noinline, noclone))    \
+TYPE f_##TYPE##_##OP##_fetch (TYPE *a, TYPE b) \
+{ \
+  return __atomic_##OP##_fetch (a, b, __ATOMIC_RELAXED);  \
+} \
+__attribute__ ((noinline, noclone))    \
+TYPE f_##TYPE##_fetch_##OP (TYPE *a, TYPE b)   \
+{ \
+  return __atomic_fetch_##OP (a, b, __ATOMIC_RELAXED);  \
+}
+
+FUNC_ATOMIC (__int128_t, and)
+FUNC_ATOMIC (__int128_t, nand)
+FUNC_ATOMIC (__int128_t, or)
+FUNC_ATOMIC (__int128_t, xor)
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-2b.c 
b/gcc/testsuite/gcc.target/i386/pr126293-2b.c
new file mode 100644
index 000000000000..b74579c7cb04
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-2b.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -march=x86-64 -m128bit-atomic" } */
+
+#include <stdlib.h>
+#include "pr126293-2a.c"
+
+#define FUNC_ATOMIC_RELAX(TYPE, OP) \
+__attribute__ ((noinline, noclone, target ("relax-cmpxchg-loop")))     \
+TYPE relax_##TYPE##_##OP##_fetch (TYPE *a, TYPE b)     \
+{ \
+  return __atomic_##OP##_fetch (a, b, __ATOMIC_RELAXED);  \
+} \
+__attribute__ ((noinline, noclone, target ("relax-cmpxchg-loop")))     \
+TYPE relax_##TYPE##_fetch_##OP (TYPE *a, TYPE b)       \
+{ \
+  return __atomic_fetch_##OP (a, b, __ATOMIC_RELAXED);  \
+}
+
+FUNC_ATOMIC_RELAX (__int128_t, and)
+FUNC_ATOMIC_RELAX (__int128_t, nand)
+FUNC_ATOMIC_RELAX (__int128_t, or)
+FUNC_ATOMIC_RELAX (__int128_t, xor)
+
+#define TEST_ATOMIC_FETCH_LOGIC(TYPE, OP) \
+{ \
+  TYPE a = 11, b = 101, res, exp; \
+  TYPE c = 11, d = 101;        \
+  res = relax_##TYPE##_##OP##_fetch (&a, b); \
+  exp = f_##TYPE##_##OP##_fetch (&c, d);  \
+  if (res != exp || a != c) \
+    abort (); \
+  a = c = 21, b = d = 92; \
+  res = relax_##TYPE##_fetch_##OP (&a, b); \
+  exp = f_##TYPE##_fetch_##OP (&c, d);  \
+  if (res != exp || a != c) \
+    abort (); \
+}
+
+__attribute__((noinline))
+static void
+do_test (void)
+{
+  TEST_ATOMIC_FETCH_LOGIC (__int128_t, and)
+  TEST_ATOMIC_FETCH_LOGIC (__int128_t, nand)
+  TEST_ATOMIC_FETCH_LOGIC (__int128_t, or)
+  TEST_ATOMIC_FETCH_LOGIC (__int128_t, xor)
+}
+
+int
+main (void)
+{
+  if (__builtin_cpu_supports ("cmpxchg16b"))
+    do_test ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-3a.c 
b/gcc/testsuite/gcc.target/i386/pr126293-3a.c
new file mode 100644
index 000000000000..48630f5f6b6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-3a.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -march=x86-64 -m128bit-atomic 
-mrelax-cmpxchg-loop" } */
+/* { dg-final { scan-assembler-times "lock;?\[ \\t\]+cmpxchg16b" 1 } } */
+
+#include <stdint.h>
+
+#define FUNC_CMPXCHG(TYPE) \
+__attribute__ ((noinline, noclone))    \
+TYPE f_##TYPE##_cmpxchg (TYPE *lock, TYPE newval, TYPE oldval)  \
+{ \
+  do  \
+  { \
+    newval = oldval | 1;  \
+  } while (! __atomic_compare_exchange_n (lock, &oldval, newval,  \
+                                         0, __ATOMIC_RELEASE,  \
+                                         __ATOMIC_RELAXED));  \
+  return *lock;        \
+}
+
+
+FUNC_CMPXCHG (__int128_t)
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-3b.c 
b/gcc/testsuite/gcc.target/i386/pr126293-3b.c
new file mode 100644
index 000000000000..1e9d1872f8ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-3b.c
@@ -0,0 +1,45 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -march=x86-64 -m128bit-atomic" } */
+
+#include <stdlib.h>
+#include "pr126293-3a.c"
+
+#define FUNC_CMPXCHG_RELAX(TYPE) \
+__attribute__ ((noinline, noclone, target ("relax-cmpxchg-loop")))     \
+TYPE relax_##TYPE##_cmpxchg (TYPE *lock, TYPE newval, TYPE oldval)  \
+{ \
+  do  \
+  { \
+    newval = oldval | 1;  \
+  } while (! __atomic_compare_exchange_n (lock, &oldval, newval,  \
+                                         0, __ATOMIC_RELEASE,  \
+                                         __ATOMIC_RELAXED));  \
+  return *lock;        \
+}
+
+FUNC_CMPXCHG_RELAX (__int128_t)
+
+#define TEST_CMPXCHG_LOOP(TYPE)        \
+{ \
+  TYPE a = 11, b = 20, c = 11, res, exp; \
+  TYPE d = 11, e = 20, f = 11; \
+  res = relax_##TYPE##_cmpxchg (&a, b, c); \
+  exp = f_##TYPE##_cmpxchg (&d, e, f); \
+  if (res != exp || a != d) \
+    abort (); \
+}
+
+__attribute__((noinline))
+static void
+do_test (void)
+{
+  TEST_CMPXCHG_LOOP (__int128_t)
+}
+
+int
+main (void)
+{
+  if (__builtin_cpu_supports ("cmpxchg16b"))
+    do_test ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4a.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4a.c
new file mode 100644
index 000000000000..547f5fc9469b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4a.c
@@ -0,0 +1,31 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movq    %rdi, %xmm0
+**     movq    %rsi, %xmm1
+**     punpcklqdq      %xmm1, %xmm0
+**     movaps  %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#ifndef ATTRIBUTE
+#define ATTRIBUTE
+#endif
+
+extern _Atomic __uint128_t store;
+
+ATTRIBUTE
+void
+func (__uint128_t i)
+{
+  store = i;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4b.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4b.c
new file mode 100644
index 000000000000..8a3ec685db80
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4b.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=diamondrapids" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     vmovq   %rdi, %xmm1
+**     vpinsrq \$1, %rsi, %xmm1, %xmm0
+**     vmovdqa %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4c.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4c.c
new file mode 100644
index 000000000000..f1848cdb5433
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4c.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=nehalem -mavx" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     vmovq   %rdi, %xmm1
+**     vpinsrq \$1, %rsi, %xmm1, %xmm0
+**     vmovdqa %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4d.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4d.c
new file mode 100644
index 000000000000..39caeee001b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4d.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=znver1" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     vmovq   %rdi, %xmm1
+**     vpinsrq \$1, %rsi, %xmm1, %xmm0
+**     vmovdqa %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4e.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4e.c
new file mode 100644
index 000000000000..9981ae138b54
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4e.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=yongfeng" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     vmovq   %rdi, %xmm1
+**     vpinsrq \$1, %rsi, %xmm1, %xmm0
+**     vmovdqa %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4f.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4f.c
new file mode 100644
index 000000000000..3931a3e8bcc2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4f.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=diamondrapids 
-mno-avx" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movq    %rdi, %xmm0
+**     pinsrq  \$1, %rsi, %xmm0
+**     movaps  %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4g.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4g.c
new file mode 100644
index 000000000000..77ff16507ef6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4g.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=sandybridge -mno-avx" 
} */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movq    %rdi, %xmm0
+**     pinsrq  \$1, %rsi, %xmm0
+**     movaps  %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4h.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4h.c
new file mode 100644
index 000000000000..6327e4185fe5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4h.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=ivybridge -mno-avx" } 
*/
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movq    %rdi, %xmm0
+**     pinsrq  \$1, %rsi, %xmm0
+**     movaps  %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4i.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4i.c
new file mode 100644
index 000000000000..db9f8b49ec39
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4i.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=znver1 -mno-avx" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movq    %rdi, %xmm0
+**     pinsrq  \$1, %rsi, %xmm0
+**     movaps  %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4j.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4j.c
new file mode 100644
index 000000000000..1628319b5b5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4j.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=lujiazui" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movq    %rsi, %rdx
+**     movl    \$5, %ecx
+**     movq    %rdi, %rsi
+**     movl    \$store, %edi
+**     jmp     __atomic_store_16
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4k.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4k.c
new file mode 100644
index 000000000000..76a379275757
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4k.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=skylake -mno-cx16" } 
*/
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movq    %rsi, %rdx
+**     movl    \$5, %ecx
+**     movq    %rdi, %rsi
+**     movl    \$store, %edi
+**     jmp     __atomic_store_16
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4l.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4l.c
new file mode 100644
index 000000000000..4a80ed40efa6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4l.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=skylake -mno-sse" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movq    %rsi, %rdx
+**     movl    \$5, %ecx
+**     movq    %rdi, %rsi
+**     movl    \$store, %edi
+**     jmp     __atomic_store_16
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4m.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4m.c
new file mode 100644
index 000000000000..4ea11e00ff35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4m.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=grandridge" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     vmovq   %rdi, %xmm1
+**     vpinsrq \$1, %rsi, %xmm1, %xmm0
+**     vmovdqa %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4n.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4n.c
new file mode 100644
index 000000000000..f0f92b429ce5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4n.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=skylake 
-mno-128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movq    %rsi, %rdx
+**     movl    \$5, %ecx
+**     movq    %rdi, %rsi
+**     movl    \$store, %edi
+**     jmp     __atomic_store_16
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4o.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4o.c
new file mode 100644
index 000000000000..6b94a7d59a4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4o.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=c86-4g-m8" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     vmovq   %rdi, %xmm1
+**     vpinsrq \$1, %rsi, %xmm1, %xmm0
+**     vmovdqa %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4p.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4p.c
new file mode 100644
index 000000000000..9b2de450c5d2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4p.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64-v3" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     vmovq   %rdi, %xmm1
+**     vpinsrq \$1, %rsi, %xmm1, %xmm0
+**     vmovdqa %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4q.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4q.c
new file mode 100644
index 000000000000..4268a297c2c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4q.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64-v4" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     vmovq   %rdi, %xmm1
+**     vpinsrq \$1, %rsi, %xmm1, %xmm0
+**     vmovdqa %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4r.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4r.c
new file mode 100644
index 000000000000..45e8bb7e55c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4r.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     vmovq   %rdi, %xmm1
+**     vpinsrq \$1, %rsi, %xmm1, %xmm0
+**     vmovdqa %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+#define ATTRIBUTE __attribute__ ((target("arch=skylake")))
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-4s.c 
b/gcc/testsuite/gcc.target/i386/pr126293-4s.c
new file mode 100644
index 000000000000..38eb8bdac281
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-4s.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=skylake" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movq    %rsi, %rdx
+**     movl    \$5, %ecx
+**     movq    %rdi, %rsi
+**     movl    \$store, %edi
+**     jmp     __atomic_store_16
+**     .cfi_endproc
+**...
+*/
+
+#define ATTRIBUTE __attribute__ ((target("arch=x86-64")))
+#include "pr126293-4a.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-5.c 
b/gcc/testsuite/gcc.target/i386/pr126293-5.c
new file mode 100644
index 000000000000..2f0794132c9b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-5.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movdqa  load\(%rip\), %xmm0
+**     movaps  %xmm0, -24\(%rsp\)
+**     movq    -24\(%rsp\), %rax
+**     movq    -16\(%rsp\), %rdx
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+_Atomic __uint128_t load;
+
+__uint128_t
+func (void)
+{
+  return load;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-6.c 
b/gcc/testsuite/gcc.target/i386/pr126293-6.c
new file mode 100644
index 000000000000..5ad0b4b6a7ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-6.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movaps  %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+typedef int vector __attribute__((vector_size (16)));
+extern _Atomic vector store;
+
+void
+func (vector i)
+{
+  store = i;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-7.c 
b/gcc/testsuite/gcc.target/i386/pr126293-7.c
new file mode 100644
index 000000000000..0f5073ea9851
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-7.c
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movdqa  load\(%rip\), %xmm0
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+typedef int vector __attribute__((vector_size (16)));
+extern _Atomic vector load;
+
+vector
+func (void)
+{
+  return load;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-8.c 
b/gcc/testsuite/gcc.target/i386/pr126293-8.c
new file mode 100644
index 000000000000..5c9abe02dd3d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-8.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movaps  %xmm0, store\(%rip\)
+**     lock orq        \$0, \(%rsp\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+typedef float vector __attribute__((vector_size (16)));
+extern _Atomic vector store;
+
+void
+func (vector i)
+{
+  store = i;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr126293-9.c 
b/gcc/testsuite/gcc.target/i386/pr126293-9.c
new file mode 100644
index 000000000000..623498711f77
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126293-9.c
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-additional-options "-O2 -fno-pic -std=c23 -march=x86-64 
-m128bit-atomic" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target *-*-linux* } 
{^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movdqa  load\(%rip\), %xmm0
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+typedef float vector __attribute__((vector_size (16)));
+extern _Atomic vector load;
+
+vector
+func (void)
+{
+  return load;
+}

Reply via email to