[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / Transforms / AtomicExpand / ARM / cmpxchg-weak.ll
blobf7a210d631bf9570d226cdb80ea3774ad25b3c5f
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:.*]]
8 ; CHECK: [[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]]
37 ; CHECK: [[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
44   ret i32 %oldval
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:.*]]
51 ; CHECK: [[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]]:
74 ; CHECK-NOT: dmb
75 ; CHECK:     br label %[[END]]
77 ; CHECK: [[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
83   ret i1 %oldval
86 define i32 @test_cmpxchg_monotonic(ptr %addr, i32 %desired, i32 %new) {
87 ; CHECK-LABEL: @test_cmpxchg_monotonic
88 ; CHECK-NOT: dmb
89 ; CHECK:     br label %[[START:.*]]
91 ; CHECK: [[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]]:
106 ; CHECK-NOT: dmb
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]] ]
116 ; CHECK-NOT: dmb
117 ; CHECK:     br label %[[END]]
119 ; CHECK: [[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
126   ret i32 %oldval
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:.*]]
133 ; CHECK: [[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]]
162 ; CHECK: [[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
169   ret i32 %oldval