1 ; RUN: opt -atomic-expand -codegen-opt-level=1 -S -mtriple=thumbv7s-apple-ios7.0 %s | FileCheck %s
3 define i32 @test_cmpxchg_seq_cst(ptr %addr, i32 %desired, i32 %new) {
4 ; CHECK-LABEL: @test_cmpxchg_seq_cst
5 ; Intrinsic for "dmb ishst" is then expected
6 ; CHECK: br label %[[START:.*]]
9 ; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) %addr)
10 ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
11 ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
13 ; CHECK: [[FENCED_STORE]]:
14 ; CHECK: call void @llvm.arm.dmb(i32 10)
15 ; CHECK: br label %[[TRY_STORE:.*]]
17 ; CHECK: [[TRY_STORE]]:
18 ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[LOADED]], %[[FENCED_STORE]] ]
19 ; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0(i32 %new, ptr elementtype(i32) %addr)
20 ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
21 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
23 ; CHECK: [[SUCCESS_BB]]:
24 ; CHECK: call void @llvm.arm.dmb(i32 11)
25 ; CHECK: br label %[[END:.*]]
27 ; CHECK: [[NO_STORE_BB]]:
28 ; CHECK: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[LOADED]], %[[START]] ]
29 ; CHECK: call void @llvm.arm.clrex()
30 ; CHECK: br label %[[FAILURE_BB]]
32 ; CHECK: [[FAILURE_BB]]:
33 ; CHECK: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ], [ [[LOADED_TRYSTORE]], %[[TRY_STORE]] ]
34 ; CHECK: call void @llvm.arm.dmb(i32 11)
35 ; CHECK: br label %[[END]]
38 ; CHECK: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ]
39 ; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
40 ; CHECK: ret i32 [[LOADED_EXIT]]
42 %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst seq_cst
43 %oldval = extractvalue { i32, i1 } %pair, 0
47 define i1 @test_cmpxchg_weak_fail(ptr %addr, i32 %desired, i32 %new) {
48 ; CHECK-LABEL: @test_cmpxchg_weak_fail
49 ; CHECK: br label %[[START:.*]]
52 ; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) %addr)
53 ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
54 ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
56 ; CHECK: [[FENCED_STORE]]:
57 ; CHECK: call void @llvm.arm.dmb(i32 10)
58 ; CHECK: br label %[[TRY_STORE:.*]]
60 ; CHECK: [[TRY_STORE]]:
61 ; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0(i32 %new, ptr elementtype(i32) %addr)
62 ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
63 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
65 ; CHECK: [[SUCCESS_BB]]:
66 ; CHECK: call void @llvm.arm.dmb(i32 11)
67 ; CHECK: br label %[[END:.*]]
69 ; CHECK: [[NO_STORE_BB]]:
70 ; CHECK: call void @llvm.arm.clrex()
71 ; CHECK: br label %[[FAILURE_BB]]
73 ; CHECK: [[FAILURE_BB]]:
75 ; CHECK: br label %[[END]]
78 ; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
79 ; CHECK: ret i1 [[SUCCESS]]
81 %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst monotonic
82 %oldval = extractvalue { i32, i1 } %pair, 1
86 define i32 @test_cmpxchg_monotonic(ptr %addr, i32 %desired, i32 %new) {
87 ; CHECK-LABEL: @test_cmpxchg_monotonic
89 ; CHECK: br label %[[START:.*]]
92 ; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) %addr)
93 ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
94 ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
96 ; CHECK: [[FENCED_STORE]]:
97 ; CHECK-NEXT: br label %[[TRY_STORE]]
99 ; CHECK: [[TRY_STORE]]:
100 ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[LOADED]], %[[FENCED_STORE]] ]
101 ; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0(i32 %new, ptr elementtype(i32) %addr)
102 ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
103 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
105 ; CHECK: [[SUCCESS_BB]]:
107 ; CHECK: br label %[[END:.*]]
109 ; CHECK: [[NO_STORE_BB]]:
110 ; CHECK: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[LOADED]], %[[START]] ]
111 ; CHECK: call void @llvm.arm.clrex()
112 ; CHECK: br label %[[FAILURE_BB]]
114 ; CHECK: [[FAILURE_BB]]:
115 ; CHECK: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ], [ [[LOADED_TRYSTORE]], %[[TRY_STORE]] ]
117 ; CHECK: br label %[[END]]
120 ; CHECK: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ]
121 ; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
122 ; CHECK: ret i32 [[LOADED_EXIT]]
124 %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new monotonic monotonic
125 %oldval = extractvalue { i32, i1 } %pair, 0
129 define i32 @test_cmpxchg_seq_cst_minsize(ptr %addr, i32 %desired, i32 %new) minsize {
130 ; CHECK-LABEL: @test_cmpxchg_seq_cst_minsize
131 ; CHECK: br label %[[START:.*]]
134 ; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) %addr)
135 ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
136 ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
138 ; CHECK: [[FENCED_STORE]]:
139 ; CHECK: call void @llvm.arm.dmb(i32 10)
140 ; CHECK: br label %[[TRY_STORE:.*]]
142 ; CHECK: [[TRY_STORE]]:
143 ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[LOADED]], %[[FENCED_STORE]] ]
144 ; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0(i32 %new, ptr elementtype(i32) %addr)
145 ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
146 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
148 ; CHECK: [[SUCCESS_BB]]:
149 ; CHECK: call void @llvm.arm.dmb(i32 11)
150 ; CHECK: br label %[[END:.*]]
152 ; CHECK: [[NO_STORE_BB]]:
153 ; CHECK: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[LOADED]], %[[START]] ]
154 ; CHECK: call void @llvm.arm.clrex()
155 ; CHECK: br label %[[FAILURE_BB]]
157 ; CHECK: [[FAILURE_BB]]:
158 ; CHECK: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ], [ [[LOADED_TRYSTORE]], %[[TRY_STORE]] ]
159 ; CHECK: call void @llvm.arm.dmb(i32 11)
160 ; CHECK: br label %[[END]]
163 ; CHECK: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ]
164 ; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
165 ; CHECK: ret i32 [[LOADED_EXIT]]
167 %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst seq_cst
168 %oldval = extractvalue { i32, i1 } %pair, 0