From 8f2a85e0995a5bb2943bf9c5021950beaf48265e Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Fri, 13 Jun 2014 14:24:07 +0000 Subject: IR: add "cmpxchg weak" variant to support permitted failure. This commit adds a weak variant of the cmpxchg operation, as described in C++11. A cmpxchg instruction with this modifier is permitted to fail to store, even if the comparison indicated it should. As a result, cmpxchg instructions must return a flag indicating success in addition to their original iN value loaded. Thus, for uniformity *all* cmpxchg instructions now return "{ iN, i1 }". The second flag is 1 when the store succeeded. At the DAG level, a new ATOMIC_CMP_SWAP_WITH_SUCCESS node has been added as the natural representation for the new cmpxchg instructions. It is a strong cmpxchg. By default this gets Expanded to the existing ATOMIC_CMP_SWAP during Legalization, so existing backends should see no change in behaviour. If they wish to deal with the enhanced node instead, they can call setOperationAction on it. Beware: as a node with 2 results, it cannot be selected from TableGen. Currently, no use is made of the extra information provided in this patch. Test updates are almost entirely adapting the input IR to the new scheme. Summary for out of tree users: ------------------------------ + Legacy Bitcode files are upgraded during read. + Legacy assembly IR files will be invalid. + Front-ends must adapt to different type for "cmpxchg". + Backends should be unaffected by default. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210903 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Bitcode/atomic.ll | 17 +++++++++ test/Bitcode/memInstructions.3.2.ll | 60 +++++++++++++++++++++----------- test/Bitcode/weak-cmpxchg-upgrade.ll | 15 ++++++++ test/Bitcode/weak-cmpxchg-upgrade.ll.bc | Bin 0 -> 332 bytes 4 files changed, 72 insertions(+), 20 deletions(-) create mode 100644 test/Bitcode/atomic.ll create mode 100644 test/Bitcode/weak-cmpxchg-upgrade.ll create mode 100644 test/Bitcode/weak-cmpxchg-upgrade.ll.bc (limited to 'test/Bitcode') diff --git a/test/Bitcode/atomic.ll b/test/Bitcode/atomic.ll new file mode 100644 index 00000000000..37815a749b5 --- /dev/null +++ b/test/Bitcode/atomic.ll @@ -0,0 +1,17 @@ +; RUN: llvm-as %s -o - | llvm-dis | FileCheck %s + +define void @test_cmpxchg(i32* %addr, i32 %desired, i32 %new) { + cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst + ; CHECK: cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst + + cmpxchg volatile i32* %addr, i32 %desired, i32 %new seq_cst monotonic + ; CHECK: cmpxchg volatile i32* %addr, i32 %desired, i32 %new seq_cst monotonic + + cmpxchg weak i32* %addr, i32 %desired, i32 %new acq_rel acquire + ; CHECK: cmpxchg weak i32* %addr, i32 %desired, i32 %new acq_rel acquire + + cmpxchg weak volatile i32* %addr, i32 %desired, i32 %new singlethread release monotonic + ; CHECK: cmpxchg weak volatile i32* %addr, i32 %desired, i32 %new singlethread release monotonic + + ret void +} \ No newline at end of file diff --git a/test/Bitcode/memInstructions.3.2.ll b/test/Bitcode/memInstructions.3.2.ll index 21c3deb8a5a..e4cb6bdbe96 100644 --- a/test/Bitcode/memInstructions.3.2.ll +++ b/test/Bitcode/memInstructions.3.2.ll @@ -223,68 +223,88 @@ define void @cmpxchg(i32* %ptr,i32 %cmp,i32 %new){ entry: ;cmpxchg [volatile] * , , [singlethread] -; CHECK: %res1 = cmpxchg i32* %ptr, i32 %cmp, i32 %new monotonic monotonic +; CHECK: [[TMP:%[a-z0-9]+]] = cmpxchg i32* %ptr, i32 %cmp, i32 %new monotonic monotonic +; CHECK-NEXT: %res1 = extractvalue { i32, i1 } [[TMP]], 0 %res1 = cmpxchg i32* %ptr, i32 %cmp, i32 %new monotonic monotonic -; CHECK-NEXT: %res2 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new monotonic monotonic +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new monotonic monotonic +; CHECK-NEXT: %res2 = extractvalue { i32, i1 } [[TMP]], 0 %res2 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new monotonic monotonic -; CHECK-NEXT: %res3 = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread monotonic monotonic +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread monotonic monotonic +; CHECK-NEXT: %res3 = extractvalue { i32, i1 } [[TMP]], 0 %res3 = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread monotonic monotonic -; CHECK-NEXT: %res4 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread monotonic monotonic +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread monotonic monotonic +; CHECK-NEXT: %res4 = extractvalue { i32, i1 } [[TMP]], 0 %res4 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread monotonic monotonic -; CHECK-NEXT: %res5 = cmpxchg i32* %ptr, i32 %cmp, i32 %new acquire acquire +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg i32* %ptr, i32 %cmp, i32 %new acquire acquire +; CHECK-NEXT: %res5 = extractvalue { i32, i1 } [[TMP]], 0 %res5 = cmpxchg i32* %ptr, i32 %cmp, i32 %new acquire acquire -; CHECK-NEXT: %res6 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new acquire acquire +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new acquire acquire +; CHECK-NEXT: %res6 = extractvalue { i32, i1 } [[TMP]], 0 %res6 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new acquire acquire -; CHECK-NEXT: %res7 = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread acquire acquire +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread acquire acquire +; CHECK-NEXT: %res7 = extractvalue { i32, i1 } [[TMP]], 0 %res7 = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread acquire acquire -; CHECK-NEXT: %res8 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread acquire acquire +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread acquire acquire +; CHECK-NEXT: %res8 = extractvalue { i32, i1 } [[TMP]], 0 %res8 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread acquire acquire -; CHECK-NEXT: %res9 = cmpxchg i32* %ptr, i32 %cmp, i32 %new release monotonic +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg i32* %ptr, i32 %cmp, i32 %new release monotonic +; CHECK-NEXT: %res9 = extractvalue { i32, i1 } [[TMP]], 0 %res9 = cmpxchg i32* %ptr, i32 %cmp, i32 %new release monotonic -; CHECK-NEXT: %res10 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new release monotonic +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new release monotonic +; CHECK-NEXT: %res10 = extractvalue { i32, i1 } [[TMP]], 0 %res10 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new release monotonic -; CHECK-NEXT: %res11 = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread release monotonic +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread release monotonic +; CHECK-NEXT: %res11 = extractvalue { i32, i1 } [[TMP]], 0 %res11 = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread release monotonic -; CHECK-NEXT: %res12 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread release monotonic +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread release monotonic +; CHECK-NEXT: %res12 = extractvalue { i32, i1 } [[TMP]], 0 %res12 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread release monotonic -; CHECK-NEXT: %res13 = cmpxchg i32* %ptr, i32 %cmp, i32 %new acq_rel acquire +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg i32* %ptr, i32 %cmp, i32 %new acq_rel acquire +; CHECK-NEXT: %res13 = extractvalue { i32, i1 } [[TMP]], 0 %res13 = cmpxchg i32* %ptr, i32 %cmp, i32 %new acq_rel acquire -; CHECK-NEXT: %res14 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new acq_rel acquire +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new acq_rel acquire +; CHECK-NEXT: %res14 = extractvalue { i32, i1 } [[TMP]], 0 %res14 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new acq_rel acquire -; CHECK-NEXT: %res15 = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread acq_rel acquire +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread acq_rel acquire +; CHECK-NEXT: %res15 = extractvalue { i32, i1 } [[TMP]], 0 %res15 = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread acq_rel acquire -; CHECK-NEXT: %res16 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread acq_rel acquire +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread acq_rel acquire +; CHECK-NEXT: %res16 = extractvalue { i32, i1 } [[TMP]], 0 %res16 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread acq_rel acquire -; CHECK-NEXT: %res17 = cmpxchg i32* %ptr, i32 %cmp, i32 %new seq_cst seq_cst +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg i32* %ptr, i32 %cmp, i32 %new seq_cst seq_cst +; CHECK-NEXT: %res17 = extractvalue { i32, i1 } [[TMP]], 0 %res17 = cmpxchg i32* %ptr, i32 %cmp, i32 %new seq_cst seq_cst -; CHECK-NEXT: %res18 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new seq_cst seq_cst +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new seq_cst seq_cst +; CHECK-NEXT: %res18 = extractvalue { i32, i1 } [[TMP]], 0 %res18 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new seq_cst seq_cst -; CHECK-NEXT: %res19 = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread seq_cst seq_cst +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread seq_cst seq_cst +; CHECK-NEXT: %res19 = extractvalue { i32, i1 } [[TMP]], 0 %res19 = cmpxchg i32* %ptr, i32 %cmp, i32 %new singlethread seq_cst seq_cst -; CHECK-NEXT: %res20 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread seq_cst seq_cst +; CHECK-NEXT: [[TMP:%[a-z0-9]+]] = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread seq_cst seq_cst +; CHECK-NEXT: %res20 = extractvalue { i32, i1 } [[TMP]], 0 %res20 = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %new singlethread seq_cst seq_cst ret void diff --git a/test/Bitcode/weak-cmpxchg-upgrade.ll b/test/Bitcode/weak-cmpxchg-upgrade.ll new file mode 100644 index 00000000000..dbcd150633e --- /dev/null +++ b/test/Bitcode/weak-cmpxchg-upgrade.ll @@ -0,0 +1,15 @@ +; RUN: llvm-dis < %s.bc | FileCheck %s + +; cmpxchg-upgrade.ll.bc was produced by running a version of llvm-as from just +; before the IR change on this file. + +define i32 @test(i32* %addr, i32 %old, i32 %new) { +; CHECK: [[TMP:%.*]] = cmpxchg i32* %addr, i32 %old, i32 %new seq_cst monotonic +; CHECK: %val = extractvalue { i32, i1 } [[TMP]], 0 + %val = cmpxchg i32* %addr, i32 %old, i32 %new seq_cst monotonic + ret i32 %val +} + +define i32 @test(i32* %addr, i32 %old, i32 %new) { + ret i1 %val +} diff --git a/test/Bitcode/weak-cmpxchg-upgrade.ll.bc b/test/Bitcode/weak-cmpxchg-upgrade.ll.bc new file mode 100644 index 00000000000..f713c317d46 Binary files /dev/null and b/test/Bitcode/weak-cmpxchg-upgrade.ll.bc differ -- cgit v1.2.3