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(i32* %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.p0i32(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: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
19 ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
20 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
22 ; CHECK: [[SUCCESS_BB]]:
23 ; CHECK: call void @llvm.arm.dmb(i32 11)
24 ; CHECK: br label %[[END:.*]]
26 ; CHECK: [[NO_STORE_BB]]:
27 ; CHECK: call void @llvm.arm.clrex()
28 ; CHECK: br label %[[FAILURE_BB]]
30 ; CHECK: [[FAILURE_BB]]:
31 ; CHECK: call void @llvm.arm.dmb(i32 11)
32 ; CHECK: br label %[[END]]
35 ; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
36 ; CHECK: ret i32 [[LOADED]]
38 %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
39 %oldval = extractvalue { i32, i1 } %pair, 0
43 define i1 @test_cmpxchg_weak_fail(i32* %addr, i32 %desired, i32 %new) {
44 ; CHECK-LABEL: @test_cmpxchg_weak_fail
45 ; CHECK: br label %[[START:.*]]
48 ; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
49 ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
50 ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
52 ; CHECK: [[FENCED_STORE]]:
53 ; CHECK: call void @llvm.arm.dmb(i32 10)
54 ; CHECK: br label %[[TRY_STORE:.*]]
56 ; CHECK: [[TRY_STORE]]:
57 ; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
58 ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
59 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
61 ; CHECK: [[SUCCESS_BB]]:
62 ; CHECK: call void @llvm.arm.dmb(i32 11)
63 ; CHECK: br label %[[END:.*]]
65 ; CHECK: [[NO_STORE_BB]]:
66 ; CHECK: call void @llvm.arm.clrex()
67 ; CHECK: br label %[[FAILURE_BB]]
69 ; CHECK: [[FAILURE_BB]]:
71 ; CHECK: br label %[[END]]
74 ; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
75 ; CHECK: ret i1 [[SUCCESS]]
77 %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst monotonic
78 %oldval = extractvalue { i32, i1 } %pair, 1
82 define i32 @test_cmpxchg_monotonic(i32* %addr, i32 %desired, i32 %new) {
83 ; CHECK-LABEL: @test_cmpxchg_monotonic
85 ; CHECK: br label %[[START:.*]]
88 ; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
89 ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
90 ; CHECK: br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[NO_STORE_BB:.*]]
92 ; CHECK: [[TRY_STORE]]:
93 ; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
94 ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
95 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
97 ; CHECK: [[SUCCESS_BB]]:
99 ; CHECK: br label %[[END:.*]]
101 ; CHECK: [[NO_STORE_BB]]:
102 ; CHECK: call void @llvm.arm.clrex()
103 ; CHECK: br label %[[FAILURE_BB]]
105 ; CHECK: [[FAILURE_BB]]:
107 ; CHECK: br label %[[END]]
110 ; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
111 ; CHECK: ret i32 [[LOADED]]
113 %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new monotonic monotonic
114 %oldval = extractvalue { i32, i1 } %pair, 0
118 define i32 @test_cmpxchg_seq_cst_minsize(i32* %addr, i32 %desired, i32 %new) minsize {
119 ; CHECK-LABEL: @test_cmpxchg_seq_cst_minsize
120 ; CHECK: br label %[[START:.*]]
123 ; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
124 ; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
125 ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
127 ; CHECK: [[FENCED_STORE]]:
128 ; CHECK: call void @llvm.arm.dmb(i32 10)
129 ; CHECK: br label %[[TRY_STORE:.*]]
131 ; CHECK: [[TRY_STORE]]:
132 ; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
133 ; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
134 ; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
136 ; CHECK: [[SUCCESS_BB]]:
137 ; CHECK: call void @llvm.arm.dmb(i32 11)
138 ; CHECK: br label %[[END:.*]]
140 ; CHECK: [[NO_STORE_BB]]:
141 ; CHECK: call void @llvm.arm.clrex()
142 ; CHECK: br label %[[FAILURE_BB]]
144 ; CHECK: [[FAILURE_BB]]:
145 ; CHECK: call void @llvm.arm.dmb(i32 11)
146 ; CHECK: br label %[[END]]
149 ; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
150 ; CHECK: ret i32 [[LOADED]]
152 %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
153 %oldval = extractvalue { i32, i1 } %pair, 0