Extensions
Forms
2 (2 Legacy)
Data
Intel XED v2026.08.23

CMPXCHG16B is CMPXCHG8B with REX.W: it compares RDX:RAX with 16 bytes of memory and, if they match, stores RCX:RBX there, reporting the outcome in ZF. It is the double-width compare-and-swap of 64-bit code, for two words that must change together: a pointer and a version counter against the ABA problem in a lock-free stack, or the head and tail of a queue. Like CMPXCHG, it writes the memory back when the values differ, so the page must be writable either way.

The alignment rule

The operand must be aligned to 16 bytes, or the instruction raises #GP(0), with or without LOCK; Zen 5 recorded both. CMPXCHG8B has no such rule. A structure of two pointers is aligned to only 8 bytes unless declared otherwise, for example with alignas(16).

Not in the baseline

AMD’s manual calls support for it implementation dependent. It has its own CPUID bit, leaf 1, ECX bit 13 (cx16 in Linux), and belongs to x86-64-v2 rather than the baseline. Without the bit, AMD’s manual raises #UD, while Intel’s lists #GP(0) for 64-bit mode.

From C

GCC 14 and Clang 23 at -O2 emit it only with -mcx16 or a -march that includes it; otherwise both call libatomic’s __atomic_compare_exchange_16. With -mcx16:

  • Clang inlines LOCK CMPXCHG16B for __atomic_compare_exchange_n and C11’s atomic_compare_exchange_strong on 16-byte types, and pushes RBX, which is callee-saved, around it.
  • GCC inlines it only for the old __sync_val_compare_and_swap; its __atomic and C11 forms still call libatomic.
  • Clang even makes a 16-byte atomic load out of it: zeros in all four registers, then LOCK CMPXCHG16B, which either stores 0 over 0 or fails and returns the value. That load is a write, so it faults on read-only memory. With AVX (-march=x86-64-v3), Clang loads with VMOVDQA instead: Intel’s and AMD’s manuals both make aligned 16-byte loads and stores atomic on processors that report AVX (Intel’s Volume 3A, Section 11.1.1; AMD’s Volume 2, Section 7.3.2).

Forms

Every encoding of CMPXCHG16B that Intel XED knows, one row per XED instruction form (iform). How to read the notation.
InstructionEncodingRequires
CMPXCHG16B m128 64-bit mode only CMPXCHG16B_MEMdqREX.W 0F C7 /1CMPXCHG16B
LOCK CMPXCHG16B m128 64-bit mode only CMPXCHG16B_LOCK_MEMdqREX.W 0F C7 /1CMPXCHG16B

Latency and throughput

What the scheduling models of LLVM 23.1.2 give for each form, not measurements: latency / reciprocal throughput in cycles, the ports under them. A row is a model, or models that agree; a dash, a form that its processors lack. Memory forms: latency from the address, ports without the load and store units. Which processors each model covers.
Modelm128CMPXCHG16B m128
Sandy Bridge6 / 1p0156 / 1p015
Haswell22 / 4p015622 / 4p0156
Broadwell21 / 4p015621 / 4p0156
Skylake, Skylake-SP, Ice Lake23 / 4p015623 / 4p0156
Alder Lake, Sapphire Rapids32 / 4p0 p1 p5 p6 p1132 / 4p0 p1 p5 p6 p11
Lunar Lake32 / 2.83V2 V3 p0 p1 p2 p3 p4 p532 / 2.83V2 V3 p0 p1 p2 p3 p4 p5
Bonnell22 / 11p122 / 11p1
Silvermont10 / 3IEC0 IEC1 MEC10 / 3IEC0 IEC1 MEC
Piledriver3 / 69EX13 / 69EX1
Zen, Zen 2100 / 0.25100 / 0.25
Zen 34 / 14.75ALU0 ALU1 ALU2 ALU34 / 14.75ALU0 ALU1 ALU2 ALU3
Zen 42 / 10ALU0 ALU1 ALU2 ALU32 / 10ALU0 ALU1 ALU2 ALU3
Jaguar32 / 3ALU0 ALU138 / 38ALU0 ALU1

Operation

What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.

if dest.address % 16 != 0:
    fault(GP, 0)                 # m128 must be 16-byte aligned, with or
                                 # without LOCK
old = dest.read()                # with LOCK: one atomic read-modify-write
if old == rdx << 64 | rax:
    zf = 1
    dest.write(rcx << 64 | rbx)
else:
    zf = 0
    rdx = old >> 64
    rax = old
    dest.write(old)              # memory is written back all the same
# the other flags stay as they were

Run on AMD Zen 5 (EPYC 9645): 16 cases.

Operands

What each form reads and writes, as Intel XED records it: the operands of its syntax, in order, and the implicit ones that the syntax does not name. How to read.
OperandKindAction
CMPXCHG16B m128 64-bit mode only LOCK CMPXCHG16B m128 64-bit mode only
m128explicitread, conditional write
RDXimplicitread, conditional write
RAXimplicitread, conditional write
RCXimplicitread
RBXimplicitread
RFLAGSimplicitwrite

Flags

M modified; blank: not affected. How to read.
ZF
All forms
M

Attributes

What else XED records about the forms. How to read.

All forms
aligned memory operand
Memory forms without LOCK
accepts a LOCK prefix
LOCK forms
locked: atomic read-modify-write

CPUID and processors

Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.

CPUID requirements and processors of the XED ISA sets above. Alternatives are separated by “or”; processors follow XED’s chip model, whose AMD processors end with Zen 2, and the CPU data of this site for Zen 3 to Zen 6.
ISA setCPUIDProcessors
CMPXCHG16B

CMPXCHG16B
CPUID.01H:ECX[13] CMPXCHG16B

Every x86-64 processor in XED’s model and Zen 3 to Zen 6

Sources

  1. Intel XED v2026.08.23 (commit 0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model.
  2. The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s -march feature sets and AMD’s Processor Programming References, which the page of each processor cites.
  3. LLVM 23.1.2's x86 scheduling models (commit 85ac56026243): the latency, reciprocal throughput and ports of each form, as llvm-mca reports them.
  4. Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2A, page 3-196 (CMPXCHG8B/CMPXCHG16B)
  5. Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3 (325384-093, September 2026)
  6. AMD64 Architecture Programmer's Manual, Volume 2: System Programming (24593, rev. 3.46, October 2026)
  7. AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.39, October 2026)

The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The timings come from LLVM's scheduling models, part of the LLVM Project, licensed under the Apache License 2.0 with LLVM Exceptions. The text is our own.