@@ -91,9 +91,13 @@ define i8 @test_cmpxchg_i8_seqcst_seqcst(i8* %ptr, i8 %desired, i8 %newval) {
9191; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldaex.p0i8(i8* %ptr)
9292; CHECK: [[OLDVAL:%.*]] = trunc i32 %1 to i8
9393; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i8 [[OLDVAL]], %desired
94- ; CHECK: br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[NO_STORE_BB:.*]]
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:.*]]
9598
9699; CHECK: [[TRY_STORE]]:
100+ ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i8 [ [[OLDVAL]], %[[FENCED_STORE]] ]
97101; CHECK: [[NEWVAL32:%.*]] = zext i8 %newval to i32
98102; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.stlex.p0i8(i32 [[NEWVAL32]], i8* %ptr)
99103; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0
@@ -104,16 +108,19 @@ define i8 @test_cmpxchg_i8_seqcst_seqcst(i8* %ptr, i8 %desired, i8 %newval) {
104108; CHECK: br label %[[DONE:.*]]
105109
106110; CHECK: [[NO_STORE_BB]]:
111+ ; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i8 [ [[OLDVAL]], %[[LOOP]] ]
107112; CHECK-NEXT: call void @llvm.arm.clrex()
108113; CHECK-NEXT: br label %[[FAILURE_BB:.*]]
109114
110115; CHECK: [[FAILURE_BB]]:
116+ ; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i8 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ]
111117; CHECK-NOT: fence_cst
112118; CHECK: br label %[[DONE]]
113119
114120; CHECK: [[DONE]]:
121+ ; CHECK: [[LOADED_EXIT:%.*]] = phi i8 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ]
115122; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
116- ; CHECK: ret i8 [[OLDVAL ]]
123+ ; CHECK: ret i8 [[LOADED_EXIT ]]
117124
118125 %pairold = cmpxchg i8* %ptr , i8 %desired , i8 %newval seq_cst seq_cst
119126 %old = extractvalue { i8 , i1 } %pairold , 0
@@ -129,9 +136,13 @@ define i16 @test_cmpxchg_i16_seqcst_monotonic(i16* %ptr, i16 %desired, i16 %newv
129136; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldaex.p0i16(i16* %ptr)
130137; CHECK: [[OLDVAL:%.*]] = trunc i32 %1 to i16
131138; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i16 [[OLDVAL]], %desired
132- ; CHECK: br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[NO_STORE_BB:.*]]
139+ ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
140+
141+ ; CHECK: [[FENCED_STORE]]:
142+ ; CHECK-NEXT: br label %[[TRY_STORE:.*]]
133143
134144; CHECK: [[TRY_STORE]]:
145+ ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i16 [ [[OLDVAL]], %[[FENCED_STORE]] ]
135146; CHECK: [[NEWVAL32:%.*]] = zext i16 %newval to i32
136147; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.stlex.p0i16(i32 [[NEWVAL32]], i16* %ptr)
137148; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0
@@ -142,16 +153,20 @@ define i16 @test_cmpxchg_i16_seqcst_monotonic(i16* %ptr, i16 %desired, i16 %newv
142153; CHECK: br label %[[DONE:.*]]
143154
144155; CHECK: [[NO_STORE_BB]]:
156+ ; The PHI is not required.
157+ ; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i16 [ [[OLDVAL]], %[[LOOP]] ]
145158; CHECK-NEXT: call void @llvm.arm.clrex()
146159; CHECK-NEXT: br label %[[FAILURE_BB:.*]]
147160
148161; CHECK: [[FAILURE_BB]]:
162+ ; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i16 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ]
149163; CHECK-NOT: fence
150164; CHECK: br label %[[DONE]]
151165
152166; CHECK: [[DONE]]:
167+ ; CHECK: [[LOADED_EXIT:%.*]] = phi i16 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ]
153168; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
154- ; CHECK: ret i16 [[OLDVAL ]]
169+ ; CHECK: ret i16 [[LOADED_EXIT ]]
155170
156171 %pairold = cmpxchg i16* %ptr , i16 %desired , i16 %newval seq_cst monotonic
157172 %old = extractvalue { i16 , i1 } %pairold , 0
@@ -166,9 +181,13 @@ define i32 @test_cmpxchg_i32_acquire_acquire(i32* %ptr, i32 %desired, i32 %newva
166181; CHECK: [[LOOP]]:
167182; CHECK: [[OLDVAL:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* %ptr)
168183; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[OLDVAL]], %desired
169- ; CHECK: br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[NO_STORE_BB:.*]]
184+ ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
185+
186+ ; CHECK: [[FENCED_STORE]]:
187+ ; CHECK-NEXT: br label %[[TRY_STORE:.*]]
170188
171189; CHECK: [[TRY_STORE]]:
190+ ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[OLDVAL]], %[[FENCED_STORE]] ]
172191; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %newval, i32* %ptr)
173192; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0
174193; CHECK: br i1 [[TST]], label %[[SUCCESS_BB:.*]], label %[[LOOP]]
@@ -178,16 +197,19 @@ define i32 @test_cmpxchg_i32_acquire_acquire(i32* %ptr, i32 %desired, i32 %newva
178197; CHECK: br label %[[DONE:.*]]
179198
180199; CHECK: [[NO_STORE_BB]]:
200+ ; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[OLDVAL]], %[[LOOP]] ]
181201; CHECK-NEXT: call void @llvm.arm.clrex()
182202; CHECK-NEXT: br label %[[FAILURE_BB:.*]]
183203
184204; CHECK: [[FAILURE_BB]]:
205+ ; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ]
185206; CHECK-NOT: fence_cst
186207; CHECK: br label %[[DONE]]
187208
188209; CHECK: [[DONE]]:
210+ ; CHECK: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ]
189211; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
190- ; CHECK: ret i32 [[OLDVAL ]]
212+ ; CHECK: ret i32 [[LOADED_EXIT ]]
191213
192214 %pairold = cmpxchg i32* %ptr , i32 %desired , i32 %newval acquire acquire
193215 %old = extractvalue { i32 , i1 } %pairold , 0
@@ -209,9 +231,13 @@ define i64 @test_cmpxchg_i64_monotonic_monotonic(i64* %ptr, i64 %desired, i64 %n
209231; CHECK: [[HI64:%.*]] = shl i64 [[HI64_TMP]], 32
210232; CHECK: [[OLDVAL:%.*]] = or i64 [[LO64]], [[HI64]]
211233; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i64 [[OLDVAL]], %desired
212- ; CHECK: br i1 [[SHOULD_STORE]], label %[[TRY_STORE:.*]], label %[[NO_STORE_BB:.*]]
234+ ; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]]
235+
236+ ; CHECK: [[FENCED_STORE]]:
237+ ; CHECK-NEXT: br label %[[TRY_STORE:.*]]
213238
214239; CHECK: [[TRY_STORE]]:
240+ ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i64 [ [[OLDVAL]], %[[FENCED_STORE]] ]
215241; CHECK: [[NEWLO:%.*]] = trunc i64 %newval to i32
216242; CHECK: [[NEWHI_TMP:%.*]] = lshr i64 %newval, 32
217243; CHECK: [[NEWHI:%.*]] = trunc i64 [[NEWHI_TMP]] to i32
@@ -225,16 +251,19 @@ define i64 @test_cmpxchg_i64_monotonic_monotonic(i64* %ptr, i64 %desired, i64 %n
225251; CHECK: br label %[[DONE:.*]]
226252
227253; CHECK: [[NO_STORE_BB]]:
254+ ; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i64 [ [[OLDVAL]], %[[LOOP]] ]
228255; CHECK-NEXT: call void @llvm.arm.clrex()
229256; CHECK-NEXT: br label %[[FAILURE_BB:.*]]
230257
231258; CHECK: [[FAILURE_BB]]:
259+ ; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i64 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ]
232260; CHECK-NOT: fence_cst
233261; CHECK: br label %[[DONE]]
234262
235263; CHECK: [[DONE]]:
264+ ; CHECK: [[LOADED_EXIT:%.*]] = phi i64 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ]
236265; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
237- ; CHECK: ret i64 [[OLDVAL ]]
266+ ; CHECK: ret i64 [[LOADED_EXIT ]]
238267
239268 %pairold = cmpxchg i64* %ptr , i64 %desired , i64 %newval monotonic monotonic
240269 %old = extractvalue { i64 , i1 } %pairold , 0
0 commit comments