1; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - %s | FileCheck %s
2
3define i32 @test_return(i32* %p, i32 %oldval, i32 %newval) {
4; CHECK-LABEL: test_return:
5
6; CHECK: ldrex [[LOADED:r[0-9]+]], [r0]
7; CHECK: cmp [[LOADED]], r1
8; CHECK: bne [[FAILED:LBB[0-9]+_[0-9]+]]
9
10; CHECK: dmb ishst
11
12; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
13; CHECK: strex [[STATUS:r[0-9]+]], {{r[0-9]+}}, [r0]
14; CHECK: cbz [[STATUS]], [[SUCCESS:LBB[0-9]+_[0-9]+]]
15
16; CHECK: ldrex [[LOADED]], [r0]
17; CHECK: cmp [[LOADED]], r1
18; CHECK: beq [[LOOP]]
19
20; CHECK: [[FAILED]]:
21; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
22; CHECK: clrex
23; CHECK: movs r0, #0
24; CHECK: dmb ish
25; CHECK: bx lr
26
27; CHECK: [[SUCCESS]]:
28; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
29; CHECK: movs r0, #1
30; CHECK: dmb ish
31; CHECK: bx lr
32
33  %pair = cmpxchg i32* %p, i32 %oldval, i32 %newval seq_cst seq_cst
34  %success = extractvalue { i32, i1 } %pair, 1
35  %conv = zext i1 %success to i32
36  ret i32 %conv
37}
38
39define i1 @test_return_bool(i8* %value, i8 %oldValue, i8 %newValue) {
40; CHECK-LABEL: test_return_bool:
41
42; CHECK: uxtb [[OLDBYTE:r[0-9]+]], r1
43
44; CHECK: ldrexb [[LOADED:r[0-9]+]], [r0]
45; CHECK: cmp [[LOADED]], [[OLDBYTE]]
46; CHECK: bne [[FAIL:LBB[0-9]+_[0-9]+]]
47
48; CHECK: dmb ishst
49
50; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
51; CHECK: strexb [[STATUS:r[0-9]+]], {{r[0-9]+}}, [r0]
52; CHECK: cbz [[STATUS]], [[SUCCESS:LBB[0-9]+_[0-9]+]]
53
54; CHECK: ldrexb [[LOADED]], [r0]
55; CHECK: cmp [[LOADED]], [[OLDBYTE]]
56; CHECK: beq [[LOOP]]
57
58
59  ; FIXME: this eor is redundant. Need to teach DAG combine that.
60; CHECK: [[FAIL]]:
61; CHECK: clrex
62; CHECK: movs [[TMP:r[0-9]+]], #0
63; CHECK: eor r0, [[TMP]], #1
64; CHECK: bx lr
65
66; CHECK: [[SUCCESS]]:
67; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
68; CHECK: movs [[TMP:r[0-9]+]], #1
69; CHECK: eor r0, [[TMP]], #1
70; CHECK: bx lr
71
72
73  %pair = cmpxchg i8* %value, i8 %oldValue, i8 %newValue acq_rel monotonic
74  %success = extractvalue { i8, i1 } %pair, 1
75  %failure = xor i1 %success, 1
76  ret i1 %failure
77}
78
79define void @test_conditional(i32* %p, i32 %oldval, i32 %newval) {
80; CHECK-LABEL: test_conditional:
81
82; CHECK: ldrex [[LOADED:r[0-9]+]], [r0]
83; CHECK: cmp [[LOADED]], r1
84; CHECK: bne [[FAILED:LBB[0-9]+_[0-9]+]]
85
86; CHECK: dmb ishst
87
88; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
89; CHECK: strex [[STATUS:r[0-9]+]], r2, [r0]
90; CHECK: cbz [[STATUS]], [[SUCCESS:LBB[0-9]+_[0-9]+]]
91
92; CHECK: ldrex [[LOADED]], [r0]
93; CHECK: cmp [[LOADED]], r1
94; CHECK: beq [[LOOP]]
95
96; CHECK: [[FAILED]]:
97; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
98; CHECK: clrex
99; CHECK: dmb ish
100; CHECK: b.w _baz
101
102; CHECK: [[SUCCESS]]:
103; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
104; CHECK: dmb ish
105; CHECK: b.w _bar
106
107  %pair = cmpxchg i32* %p, i32 %oldval, i32 %newval seq_cst seq_cst
108  %success = extractvalue { i32, i1 } %pair, 1
109  br i1 %success, label %true, label %false
110
111true:
112  tail call void @bar() #2
113  br label %end
114
115false:
116  tail call void @baz() #2
117  br label %end
118
119end:
120  ret void
121}
122
123declare void @bar()
124declare void @baz()
125