Skip to content

Commit eade1f6

Browse files
committed
AtomicExpand: Stop trying to prune cmpxchg extractvalue users
The expansion for cmpxchg was trying to tidy up extractvalue users to directly use the lowered pieces, and then erasing the now dead extractvalues. This was making an assumption about the iteration order did not depend on those user instructions. Continue doing the replacement, but just leave the dead extractvalues. This is a minor regression, but it is of no importance since the dead instructions will just get dropped during codegen anyway.
1 parent 2d7a2c1 commit eade1f6

File tree

2 files changed

+142
-152
lines changed

2 files changed

+142
-152
lines changed

llvm/lib/CodeGen/AtomicExpandPass.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,7 +1514,6 @@ bool AtomicExpandImpl::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
15141514

15151515
// Look for any users of the cmpxchg that are just comparing the loaded value
15161516
// against the desired one, and replace them with the CFG-derived version.
1517-
SmallVector<ExtractValueInst *, 2> PrunedInsts;
15181517
for (auto *User : CI->users()) {
15191518
ExtractValueInst *EV = dyn_cast<ExtractValueInst>(User);
15201519
if (!EV)
@@ -1527,14 +1526,8 @@ bool AtomicExpandImpl::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
15271526
EV->replaceAllUsesWith(Loaded);
15281527
else
15291528
EV->replaceAllUsesWith(Success);
1530-
1531-
PrunedInsts.push_back(EV);
15321529
}
15331530

1534-
// We can remove the instructions now we're no longer iterating through them.
1535-
for (auto *EV : PrunedInsts)
1536-
EV->eraseFromParent();
1537-
15381531
if (!CI->use_empty()) {
15391532
// Some use of the full struct return that we don't understand has happened,
15401533
// so we've got to reconstruct it properly.

llvm/test/Transforms/AtomicExpand/ARM/cmpxchg-weak.ll

Lines changed: 142 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,169 +1,166 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
12
; RUN: opt -passes=atomic-expand -codegen-opt-level=1 -S -mtriple=thumbv7s-apple-ios7.0 %s | FileCheck %s
23

3-
define i32 @test_cmpxchg_seq_cst(ptr %addr, i32 %desired, i32 %new) {
4-
; CHECK-LABEL: @test_cmpxchg_seq_cst
54
; Intrinsic for "dmb ishst" is then expected
6-
; CHECK: br label %[[START:.*]]
7-
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:.*]]
12-
13-
; CHECK: [[FENCED_STORE]]:
14-
; CHECK: call void @llvm.arm.dmb(i32 10)
15-
; CHECK: br label %[[TRY_STORE:.*]]
16-
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:.*]]
22-
23-
; CHECK: [[SUCCESS_BB]]:
24-
; CHECK: call void @llvm.arm.dmb(i32 11)
25-
; CHECK: br label %[[END:.*]]
26-
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]]
31-
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]]
36-
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]]
41-
5+
define i32 @test_cmpxchg_seq_cst(ptr %addr, i32 %desired, i32 %new) {
6+
; CHECK-LABEL: define i32 @test_cmpxchg_seq_cst(
7+
; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) {
8+
; CHECK-NEXT: br label %[[CMPXCHG_START:.*]]
9+
; CHECK: [[CMPXCHG_START]]:
10+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]])
11+
; CHECK-NEXT: [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]]
12+
; CHECK-NEXT: br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]]
13+
; CHECK: [[CMPXCHG_FENCEDSTORE]]:
14+
; CHECK-NEXT: call void @llvm.arm.dmb(i32 10)
15+
; CHECK-NEXT: br label %[[CMPXCHG_TRYSTORE:.*]]
16+
; CHECK: [[CMPXCHG_TRYSTORE]]:
17+
; CHECK-NEXT: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ]
18+
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]])
19+
; CHECK-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0
20+
; CHECK-NEXT: br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]]
21+
; CHECK: [[CMPXCHG_RELEASEDLOAD:.*:]]
22+
; CHECK-NEXT: unreachable
23+
; CHECK: [[CMPXCHG_SUCCESS]]:
24+
; CHECK-NEXT: call void @llvm.arm.dmb(i32 11)
25+
; CHECK-NEXT: br label %[[CMPXCHG_END:.*]]
26+
; CHECK: [[CMPXCHG_NOSTORE]]:
27+
; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ]
28+
; CHECK-NEXT: call void @llvm.arm.clrex()
29+
; CHECK-NEXT: br label %[[CMPXCHG_FAILURE]]
30+
; CHECK: [[CMPXCHG_FAILURE]]:
31+
; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ]
32+
; CHECK-NEXT: call void @llvm.arm.dmb(i32 11)
33+
; CHECK-NEXT: br label %[[CMPXCHG_END]]
34+
; CHECK: [[CMPXCHG_END]]:
35+
; CHECK-NEXT: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ]
36+
; CHECK-NEXT: [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ]
37+
; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i32, i1 } poison, i32 [[LOADED_EXIT]], 0
38+
; CHECK-NEXT: [[TMP4:%.*]] = insertvalue { i32, i1 } [[TMP3]], i1 [[SUCCESS1]], 1
39+
; CHECK-NEXT: [[OLDVAL:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
40+
; CHECK-NEXT: ret i32 [[LOADED_EXIT]]
41+
;
4242
%pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst seq_cst
4343
%oldval = extractvalue { i32, i1 } %pair, 0
4444
ret i32 %oldval
4545
}
4646

4747
define i1 @test_cmpxchg_weak_fail(ptr %addr, i32 %desired, i32 %new) {
48-
; CHECK-LABEL: @test_cmpxchg_weak_fail
49-
; CHECK: br label %[[START:.*]]
50-
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:.*]]
55-
56-
; CHECK: [[FENCED_STORE]]:
57-
; CHECK: call void @llvm.arm.dmb(i32 10)
58-
; CHECK: br label %[[TRY_STORE:.*]]
59-
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:.*]]
64-
65-
; CHECK: [[SUCCESS_BB]]:
66-
; CHECK: call void @llvm.arm.dmb(i32 11)
67-
; CHECK: br label %[[END:.*]]
68-
69-
; CHECK: [[NO_STORE_BB]]:
70-
; CHECK: call void @llvm.arm.clrex()
71-
; CHECK: br label %[[FAILURE_BB]]
72-
73-
; CHECK: [[FAILURE_BB]]:
74-
; CHECK-NOT: dmb
75-
; CHECK: br label %[[END]]
76-
77-
; CHECK: [[END]]:
78-
; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
79-
; CHECK: ret i1 [[SUCCESS]]
80-
48+
; CHECK-LABEL: define i1 @test_cmpxchg_weak_fail(
49+
; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) {
50+
; CHECK-NEXT: br label %[[CMPXCHG_START:.*]]
51+
; CHECK: [[CMPXCHG_START]]:
52+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]])
53+
; CHECK-NEXT: [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]]
54+
; CHECK-NEXT: br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]]
55+
; CHECK: [[CMPXCHG_FENCEDSTORE]]:
56+
; CHECK-NEXT: call void @llvm.arm.dmb(i32 10)
57+
; CHECK-NEXT: br label %[[CMPXCHG_TRYSTORE:.*]]
58+
; CHECK: [[CMPXCHG_TRYSTORE]]:
59+
; CHECK-NEXT: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ]
60+
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]])
61+
; CHECK-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0
62+
; CHECK-NEXT: br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]]
63+
; CHECK: [[CMPXCHG_RELEASEDLOAD:.*:]]
64+
; CHECK-NEXT: unreachable
65+
; CHECK: [[CMPXCHG_SUCCESS]]:
66+
; CHECK-NEXT: call void @llvm.arm.dmb(i32 11)
67+
; CHECK-NEXT: br label %[[CMPXCHG_END:.*]]
68+
; CHECK: [[CMPXCHG_NOSTORE]]:
69+
; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ]
70+
; CHECK-NEXT: call void @llvm.arm.clrex()
71+
; CHECK-NEXT: br label %[[CMPXCHG_FAILURE]]
72+
; CHECK: [[CMPXCHG_FAILURE]]:
73+
; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ]
74+
; CHECK-NEXT: br label %[[CMPXCHG_END]]
75+
; CHECK: [[CMPXCHG_END]]:
76+
; CHECK-NEXT: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ]
77+
; CHECK-NEXT: [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ]
78+
; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i32, i1 } poison, i32 [[LOADED_EXIT]], 0
79+
; CHECK-NEXT: [[TMP4:%.*]] = insertvalue { i32, i1 } [[TMP3]], i1 [[SUCCESS1]], 1
80+
; CHECK-NEXT: [[OLDVAL:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
81+
; CHECK-NEXT: ret i1 [[SUCCESS1]]
82+
;
8183
%pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst monotonic
8284
%oldval = extractvalue { i32, i1 } %pair, 1
8385
ret i1 %oldval
8486
}
8587

8688
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:.*]]
90-
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:.*]]
95-
96-
; CHECK: [[FENCED_STORE]]:
97-
; CHECK-NEXT: br label %[[TRY_STORE]]
98-
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:.*]]
104-
105-
; CHECK: [[SUCCESS_BB]]:
106-
; CHECK-NOT: dmb
107-
; CHECK: br label %[[END:.*]]
108-
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]]
113-
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]]
118-
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]]
123-
89+
; CHECK-LABEL: define i32 @test_cmpxchg_monotonic(
90+
; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) {
91+
; CHECK-NEXT: br label %[[CMPXCHG_START:.*]]
92+
; CHECK: [[CMPXCHG_START]]:
93+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]])
94+
; CHECK-NEXT: [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]]
95+
; CHECK-NEXT: br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]]
96+
; CHECK: [[CMPXCHG_FENCEDSTORE]]:
97+
; CHECK-NEXT: br label %[[CMPXCHG_TRYSTORE:.*]]
98+
; CHECK: [[CMPXCHG_TRYSTORE]]:
99+
; CHECK-NEXT: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ]
100+
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]])
101+
; CHECK-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0
102+
; CHECK-NEXT: br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]]
103+
; CHECK: [[CMPXCHG_RELEASEDLOAD:.*:]]
104+
; CHECK-NEXT: unreachable
105+
; CHECK: [[CMPXCHG_SUCCESS]]:
106+
; CHECK-NEXT: br label %[[CMPXCHG_END:.*]]
107+
; CHECK: [[CMPXCHG_NOSTORE]]:
108+
; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ]
109+
; CHECK-NEXT: call void @llvm.arm.clrex()
110+
; CHECK-NEXT: br label %[[CMPXCHG_FAILURE]]
111+
; CHECK: [[CMPXCHG_FAILURE]]:
112+
; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ]
113+
; CHECK-NEXT: br label %[[CMPXCHG_END]]
114+
; CHECK: [[CMPXCHG_END]]:
115+
; CHECK-NEXT: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ]
116+
; CHECK-NEXT: [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ]
117+
; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i32, i1 } poison, i32 [[LOADED_EXIT]], 0
118+
; CHECK-NEXT: [[TMP4:%.*]] = insertvalue { i32, i1 } [[TMP3]], i1 [[SUCCESS1]], 1
119+
; CHECK-NEXT: [[OLDVAL:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
120+
; CHECK-NEXT: ret i32 [[LOADED_EXIT]]
121+
;
124122
%pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new monotonic monotonic
125123
%oldval = extractvalue { i32, i1 } %pair, 0
126124
ret i32 %oldval
127125
}
128126

129127
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:.*]]
132-
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:.*]]
137-
138-
; CHECK: [[FENCED_STORE]]:
139-
; CHECK: call void @llvm.arm.dmb(i32 10)
140-
; CHECK: br label %[[TRY_STORE:.*]]
141-
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:.*]]
147-
148-
; CHECK: [[SUCCESS_BB]]:
149-
; CHECK: call void @llvm.arm.dmb(i32 11)
150-
; CHECK: br label %[[END:.*]]
151-
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]]
156-
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]]
161-
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]]
166-
128+
; CHECK-LABEL: define i32 @test_cmpxchg_seq_cst_minsize(
129+
; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) #[[ATTR0:[0-9]+]] {
130+
; CHECK-NEXT: br label %[[CMPXCHG_START:.*]]
131+
; CHECK: [[CMPXCHG_START]]:
132+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]])
133+
; CHECK-NEXT: [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]]
134+
; CHECK-NEXT: br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]]
135+
; CHECK: [[CMPXCHG_FENCEDSTORE]]:
136+
; CHECK-NEXT: call void @llvm.arm.dmb(i32 10)
137+
; CHECK-NEXT: br label %[[CMPXCHG_TRYSTORE:.*]]
138+
; CHECK: [[CMPXCHG_TRYSTORE]]:
139+
; CHECK-NEXT: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ]
140+
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]])
141+
; CHECK-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0
142+
; CHECK-NEXT: br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]]
143+
; CHECK: [[CMPXCHG_RELEASEDLOAD:.*:]]
144+
; CHECK-NEXT: unreachable
145+
; CHECK: [[CMPXCHG_SUCCESS]]:
146+
; CHECK-NEXT: call void @llvm.arm.dmb(i32 11)
147+
; CHECK-NEXT: br label %[[CMPXCHG_END:.*]]
148+
; CHECK: [[CMPXCHG_NOSTORE]]:
149+
; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ]
150+
; CHECK-NEXT: call void @llvm.arm.clrex()
151+
; CHECK-NEXT: br label %[[CMPXCHG_FAILURE]]
152+
; CHECK: [[CMPXCHG_FAILURE]]:
153+
; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ]
154+
; CHECK-NEXT: call void @llvm.arm.dmb(i32 11)
155+
; CHECK-NEXT: br label %[[CMPXCHG_END]]
156+
; CHECK: [[CMPXCHG_END]]:
157+
; CHECK-NEXT: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ]
158+
; CHECK-NEXT: [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ]
159+
; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i32, i1 } poison, i32 [[LOADED_EXIT]], 0
160+
; CHECK-NEXT: [[TMP4:%.*]] = insertvalue { i32, i1 } [[TMP3]], i1 [[SUCCESS1]], 1
161+
; CHECK-NEXT: [[OLDVAL:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
162+
; CHECK-NEXT: ret i32 [[LOADED_EXIT]]
163+
;
167164
%pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst seq_cst
168165
%oldval = extractvalue { i32, i1 } %pair, 0
169166
ret i32 %oldval

0 commit comments

Comments
 (0)