1; RUN: opt -atomic-expand -S -mtriple=thumbv7s-apple-ios7.0 %s | FileCheck %s
2
3define 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 %[[NO_STORE_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: [[NO_STORE_BB]]:
24; CHECK:     call void @llvm.arm.clrex()
25; CHECK:     br label %[[FAILURE_BB]]
26
27; CHECK: [[FAILURE_BB]]:
28; CHECK:     call void @llvm.arm.dmb(i32 11)
29; CHECK:     br label %[[END]]
30
31; CHECK: [[END]]:
32; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
33; CHECK:     ret i32 [[LOADED]]
34
35  %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
36  %oldval = extractvalue { i32, i1 } %pair, 0
37  ret i32 %oldval
38}
39
40define i1 @test_cmpxchg_weak_fail(i32* %addr, i32 %desired, i32 %new) {
41; CHECK-LABEL: @test_cmpxchg_weak_fail
42; CHECK:     call void @llvm.arm.dmb(i32 10)
43; CHECK:     br label %[[START:.*]]
44
45; CHECK: [[START]]:
46; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
47; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
48; CHECK:     br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[NO_STORE_BB:.*]]
49
50; CHECK: [[TRY_STORE]]:
51; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
52; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
53; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
54
55; CHECK: [[SUCCESS_BB]]:
56; CHECK:     call void @llvm.arm.dmb(i32 11)
57; CHECK:     br label %[[END:.*]]
58
59; CHECK: [[NO_STORE_BB]]:
60; CHECK:     call void @llvm.arm.clrex()
61; CHECK:     br label %[[FAILURE_BB]]
62
63; CHECK: [[FAILURE_BB]]:
64; CHECK-NOT: dmb
65; CHECK:     br label %[[END]]
66
67; CHECK: [[END]]:
68; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
69; CHECK:     ret i1 [[SUCCESS]]
70
71  %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst monotonic
72  %oldval = extractvalue { i32, i1 } %pair, 1
73  ret i1 %oldval
74}
75
76define i32 @test_cmpxchg_monotonic(i32* %addr, i32 %desired, i32 %new) {
77; CHECK-LABEL: @test_cmpxchg_monotonic
78; CHECK-NOT: dmb
79; CHECK:     br label %[[START:.*]]
80
81; CHECK: [[START]]:
82; CHECK:     [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
83; CHECK:     [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired
84; CHECK:     br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[NO_STORE_BB:.*]]
85
86; CHECK: [[TRY_STORE]]:
87; CHECK:     [[STREX:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %new, i32* %addr)
88; CHECK:     [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0
89; CHECK:     br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]]
90
91; CHECK: [[SUCCESS_BB]]:
92; CHECK-NOT: dmb
93; CHECK:     br label %[[END:.*]]
94
95; CHECK: [[NO_STORE_BB]]:
96; CHECK:     call void @llvm.arm.clrex()
97; CHECK:     br label %[[FAILURE_BB]]
98
99; CHECK: [[FAILURE_BB]]:
100; CHECK-NOT: dmb
101; CHECK:     br label %[[END]]
102
103; CHECK: [[END]]:
104; CHECK:     [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
105; CHECK:     ret i32 [[LOADED]]
106
107  %pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new monotonic monotonic
108  %oldval = extractvalue { i32, i1 } %pair, 0
109  ret i32 %oldval
110}
111