diff --git a/docs/LangRef.html b/docs/LangRef.html index 40affb7e917..0c07f12ecfb 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -54,6 +54,7 @@
Note that program order does not introduce happens-before edges @@ -1536,8 +1540,9 @@ any write to the same byte, except:
write.Atomic instructions (cmpxchg
,
+atomicrmw
, and
+fence
) take an ordering parameter
+that determines which other atomic instructions on the same address they
+synchronize with. These semantics are borrowed from Java and C++0x,
+but are somewhat more colloquial. If these descriptions aren't precise enough,
+check those specs. fence
instructions
+treat these orderings somewhat differently since they don't take an address.
+See that instruction's documentation for details.
unordered
monotonic
unordered
, there is a single
+total order for modifications by monotonic
operations on each
+address. All modification orders must be compatible with the happens-before
+order. There is no guarantee that the modification orders can be combined to
+a global total order for the whole program (and this often will not be
+possible). The read in an atomic read-modify-write operation
+(cmpxchg
and
+atomicrmw
)
+reads the value in the modification order immediately before the value it
+writes. If one atomic read happens before another atomic read of the same
+address, the later read must see the same value or a later value in the
+address's modification order. This disallows reordering of
+monotonic
(or stronger) operations on the same address. If an
+address is written monotonic
ally by one thread, and other threads
+monotonic
ally read that address repeatedly, the other threads must
+eventually see the write. This is intended to model C++'s relaxed atomic
+variables.acquire
monotonic
, if this operation
+reads a value written by a release
atomic operation, it
+synchronizes-with that operation.release
monotonic
,
+a synchronizes-with edge may be formed by an acquire
+operation.acq_rel
(acquire+release)acquire
and release
operation on its address.seq_cst
(sequentially consistent)acq_rel
+(acquire
for an operation which only reads, release
+for an operation which only writes), there is a global total order on all
+sequentially-consistent operations on all addresses, which is consistent with
+the happens-before partial order and with the modification orders of
+all the affected addresses. Each sequentially-consistent read sees the last
+preceding write to the same address in this global order. This is intended
+to model C++'s sequentially-consistent atomic variables and Java's volatile
+shared variables.If an atomic operation is marked singlethread
,
+it only synchronizes with or participates in modification and seq_cst
+total orderings with other operations running in the same thread (for example,
+in signal handlers).
+ [volatile] cmpxchg <ty>* <pointer>, <ty> <cmp>, <ty> <new> [singlethread] <ordering> ; yields {ty} ++ +
The 'cmpxchg' instruction is used to atomically modify memory. +It loads a value in memory and compares it to a given value. If they are +equal, it stores a new value into the memory.
+ +There are three arguments to the 'cmpxchg
' instruction: an
+address to operate on, a value to compare to the value currently be at that
+address, and a new value to place at that address if the compared values are
+equal. The type of '<cmp>' must be an integer type whose
+bit width is a power of two greater than or equal to eight and less than
+or equal to a target-specific size limit. '<cmp>' and
+'<new>' must have the same type, and the type of
+'<pointer>' must be a pointer to that type. If the
+cmpxchg
is marked as volatile
, then the
+optimizer is not allowed to modify the number or order of execution
+of this cmpxchg
with other volatile
+operations.
The ordering argument specifies how this
+cmpxchg
synchronizes with other atomic operations.
The optional "singlethread
" argument declares that the
+cmpxchg
is only atomic with respect to code (usually signal
+handlers) running in the same thread as the cmpxchg
. Otherwise the
+cmpxchg is atomic with respect to all other code in the system.
The pointer passed into cmpxchg must have alignment greater than or equal to +the size in memory of the operand. + +
The contents of memory at the location specified by the +'<pointer>' operand is read and compared to +'<cmp>'; if the read value is the equal, +'<new>' is written. The original value at the location +is returned. + +
A successful cmpxchg
is a read-modify-write instruction for the
+purpose of identifying release sequences. A
+failed cmpxchg
is equivalent to an atomic load with an ordering
+parameter determined by dropping any release
part of the
+cmpxchg
's ordering.
+entry: + %orig = atomic load i32* %ptr unordered ; yields {i32} + br label %loop + +loop: + %cmp = phi i32 [ %orig, %entry ], [%old, %loop] + %squared = mul i32 %cmp, %cmp + %old = cmpxchg i32* %ptr, i32 %cmp, i32 %squared ; yields {i32} + %success = icmp eq i32 %cmp, %old + br i1 %success, label %done, label %loop + +done: + ... ++ +
+ [volatile] atomicrmw <operation> <ty>* <pointer>, <ty> <value> [singlethread] <ordering> ; yields {ty} ++ +
The 'atomicrmw' instruction is used to atomically modify memory.
+ +There are three arguments to the 'atomicrmw
' instruction: an
+operation to apply, an address whose value to modify, an argument to the
+operation. The operation must be one of the following keywords:
The type of '<value>' must be an integer type whose
+bit width is a power of two greater than or equal to eight and less than
+or equal to a target-specific size limit. The type of the
+'<pointer>
' operand must be a pointer to that type.
+If the atomicrmw
is marked as volatile
, then the
+optimizer is not allowed to modify the number or order of execution of this
+atomicrmw
with other volatile
+ operations.
The contents of memory at the location specified by the +'<pointer>' operand are atomically read, modified, and written +back. The original value at the location is returned. The modification is +specified by the operation argument:
+ +*ptr = val
*ptr = *ptr + val
*ptr = *ptr - val
*ptr = *ptr & val
*ptr = ~(*ptr & val)
*ptr = *ptr | val
*ptr = *ptr ^ val
*ptr = *ptr > val ? *ptr : val
(using a signed comparison)*ptr = *ptr < val ? *ptr : val
(using a signed comparison)*ptr = *ptr > val ? *ptr : val
(using an unsigned comparison)*ptr = *ptr < val ? *ptr : val
(using an unsigned comparison)+ %old = atomicrmw add i32* %ptr, i32 1 acquire ; yields {i32} ++ +