Use target-dependent emitLeading/TrailingFence instead of the target-independent...
[oota-llvm.git] / test / Transforms / AtomicExpand / ARM / cmpxchg-weak.ll
1 ; RUN: opt -atomic-expand -S -mtriple=thumbv7s-apple-ios7.0 %s | FileCheck %s
2
3 define i32 @test_cmpxchg_seq_cst(i32* %addr, i32 %desired, i32 %new) {
4 ; CHECK-LABEL: @test_cmpxchg_seq_cst
5 ; Intrinsic for "dmb ishst" is then expected
6 ; CHECK:     call void @llvm.arm.dmb(i32 10)
7 ; CHECK:     br label %[[START:.*]]
8
9 ; CHECK: [[START]]:
10 ; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
11 ; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
12 ; CHECK:     br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[FAILURE_BB:.*]]
13
14 ; CHECK: [[TRY_STORE]]:
15 ; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
16 ; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
17 ; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB]]
18
19 ; CHECK: [[SUCCESS_BB]]:
20 ; CHECK:     call void @llvm.arm.dmb(i32 11)
21 ; CHECK:     br label %[[END:.*]]
22
23 ; CHECK: [[FAILURE_BB]]:
24 ; CHECK:     call void @llvm.arm.dmb(i32 11)
25 ; CHECK:     br label %[[END]]
26
27 ; CHECK: [[END]]:
28 ; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
29 ; CHECK:     ret i32 [[LOADED]]
30
31   %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
32   %oldval = extractvalue { i32, i1 } %pair, 0
33   ret i32 %oldval
34 }
35
36 define i1 @test_cmpxchg_weak_fail(i32* %addr, i32 %desired, i32 %new) {
37 ; CHECK-LABEL: @test_cmpxchg_weak_fail
38 ; CHECK:     call void @llvm.arm.dmb(i32 10)
39 ; CHECK:     br label %[[START:.*]]
40
41 ; CHECK: [[START]]:
42 ; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
43 ; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
44 ; CHECK:     br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[FAILURE_BB:.*]]
45
46 ; CHECK: [[TRY_STORE]]:
47 ; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
48 ; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
49 ; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
50
51 ; CHECK: [[SUCCESS_BB]]:
52 ; CHECK:     call void @llvm.arm.dmb(i32 11)
53 ; CHECK:     br label %[[END:.*]]
54
55 ; CHECK: [[FAILURE_BB]]:
56 ; CHECK-NOT: dmb
57 ; CHECK:     br label %[[END]]
58
59 ; CHECK: [[END]]:
60 ; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
61 ; CHECK:     ret i1 [[SUCCESS]]
62
63   %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst monotonic
64   %oldval = extractvalue { i32, i1 } %pair, 1
65   ret i1 %oldval
66 }
67
68 define i32 @test_cmpxchg_monotonic(i32* %addr, i32 %desired, i32 %new) {
69 ; CHECK-LABEL: @test_cmpxchg_monotonic
70 ; CHECK-NOT: dmb
71 ; CHECK:     br label %[[START:.*]]
72
73 ; CHECK: [[START]]:
74 ; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
75 ; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
76 ; CHECK:     br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[FAILURE_BB:.*]]
77
78 ; CHECK: [[TRY_STORE]]:
79 ; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
80 ; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
81 ; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
82
83 ; CHECK: [[SUCCESS_BB]]:
84 ; CHECK-NOT: dmb
85 ; CHECK:     br label %[[END:.*]]
86
87 ; CHECK: [[FAILURE_BB]]:
88 ; CHECK-NOT: dmb
89 ; CHECK:     br label %[[END]]
90
91 ; CHECK: [[END]]:
92 ; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
93 ; CHECK:     ret i32 [[LOADED]]
94
95   %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new monotonic monotonic
96   %oldval = extractvalue { i32, i1 } %pair, 0
97   ret i32 %oldval
98 }