diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/Atomics.rst | 10 | ||||
-rw-r--r-- | docs/LangRef.rst | 26 |
2 files changed, 21 insertions, 15 deletions
diff --git a/docs/Atomics.rst b/docs/Atomics.rst index 1243f34548..5f17c6154f 100644 --- a/docs/Atomics.rst +++ b/docs/Atomics.rst @@ -110,8 +110,7 @@ where threads and signals are involved. ``cmpxchg`` and ``atomicrmw`` are essentially like an atomic load followed by an atomic store (where the store is conditional for ``cmpxchg``), but no other -memory operation can happen on any thread between the load and store. Note that -LLVM's cmpxchg does not provide quite as many options as the C++0x version. +memory operation can happen on any thread between the load and store. A ``fence`` provides Acquire and/or Release ordering which is not part of another operation; it is normally used along with Monotonic memory operations. @@ -430,10 +429,9 @@ other ``atomicrmw`` operations generate a loop with ``LOCK CMPXCHG``. Depending on the users of the result, some ``atomicrmw`` operations can be translated into operations like ``LOCK AND``, but that does not work in general. -On ARM, MIPS, and many other RISC architectures, Acquire, Release, and -SequentiallyConsistent semantics require barrier instructions for every such +On ARM (before v8), MIPS, and many other RISC architectures, Acquire, Release, +and SequentiallyConsistent semantics require barrier instructions for every such operation. Loads and stores generate normal instructions. ``cmpxchg`` and ``atomicrmw`` can be represented using a loop with LL/SC-style instructions which take some sort of exclusive lock on a cache line (``LDREX`` and ``STREX`` -on ARM, etc.). At the moment, the IR does not provide any way to represent a -weak ``cmpxchg`` which would not require a loop. +on ARM, etc.). diff --git a/docs/LangRef.rst b/docs/LangRef.rst index ee95cb9f85..8958505e9d 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -5059,14 +5059,14 @@ Syntax: :: - cmpxchg [volatile] <ty>* <pointer>, <ty> <cmp>, <ty> <new> [singlethread] <success ordering> <failure ordering> ; yields {ty} + cmpxchg [weak] [volatile] <ty>* <pointer>, <ty> <cmp>, <ty> <new> [singlethread] <success ordering> <failure ordering> ; yields { <ty>, i1 } Overview: """"""""" 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. +equal, it tries to store a new value into the memory. Arguments: """""""""" @@ -5099,10 +5099,17 @@ equal to the size in memory of the operand. Semantics: """""""""" -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. +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, the +'``<new>``' is written. The original value at the location is returned, together +with a flag indicating success (true) or failure (false). + +If the cmpxchg operation is marked as ``weak`` then a spurious failure is +permitted: the operation may not write ``<new>`` even if the comparison +matched. + +If the cmpxchg operation is strong (the default), the i1 value is 1 if and only +if the value loaded equals ``cmp``. A successful ``cmpxchg`` is a read-modify-write instruction for the purpose of identifying release sequences. A failed ``cmpxchg`` is equivalent to an atomic @@ -5114,14 +5121,15 @@ Example: .. code-block:: llvm entry: - %orig = atomic load i32* %ptr unordered ; yields {i32} + %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 acq_rel monotonic ; yields {i32} - %success = icmp eq i32 %cmp, %old + %val_success = cmpxchg i32* %ptr, i32 %cmp, i32 %squared acq_rel monotonic ; yields { i32, i1 } + %value_loaded = extractvalue { i32, i1 } %val_success, 0 + %success = extractvalue { i32, i1 } %val_success, 1 br i1 %success, label %done, label %loop done: |