@@ -91,9 +91,13 @@ define i8 @test_cmpxchg_i8_seqcst_seqcst(i8* %ptr, i8 %desired, i8 %newval) {
91
91
; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldaex.p0i8(i8* %ptr)
92
92
; CHECK: [[OLDVAL:%.*]] = trunc i32 %1 to i8
93
93
; 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:.*]]
95
98
96
99
; CHECK: [[TRY_STORE]]:
100
+ ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i8 [ [[OLDVAL]], %[[FENCED_STORE]] ]
97
101
; CHECK: [[NEWVAL32:%.*]] = zext i8 %newval to i32
98
102
; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.stlex.p0i8(i32 [[NEWVAL32]], i8* %ptr)
99
103
; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0
@@ -104,16 +108,19 @@ define i8 @test_cmpxchg_i8_seqcst_seqcst(i8* %ptr, i8 %desired, i8 %newval) {
104
108
; CHECK: br label %[[DONE:.*]]
105
109
106
110
; CHECK: [[NO_STORE_BB]]:
111
+ ; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i8 [ [[OLDVAL]], %[[LOOP]] ]
107
112
; CHECK-NEXT: call void @llvm.arm.clrex()
108
113
; CHECK-NEXT: br label %[[FAILURE_BB:.*]]
109
114
110
115
; CHECK: [[FAILURE_BB]]:
116
+ ; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i8 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ]
111
117
; CHECK-NOT: fence_cst
112
118
; CHECK: br label %[[DONE]]
113
119
114
120
; CHECK: [[DONE]]:
121
+ ; CHECK: [[LOADED_EXIT:%.*]] = phi i8 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ]
115
122
; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
116
- ; CHECK: ret i8 [[OLDVAL ]]
123
+ ; CHECK: ret i8 [[LOADED_EXIT ]]
117
124
118
125
%pairold = cmpxchg i8* %ptr , i8 %desired , i8 %newval seq_cst seq_cst
119
126
%old = extractvalue { i8 , i1 } %pairold , 0
@@ -129,9 +136,13 @@ define i16 @test_cmpxchg_i16_seqcst_monotonic(i16* %ptr, i16 %desired, i16 %newv
129
136
; CHECK: [[OLDVAL32:%.*]] = call i32 @llvm.arm.ldaex.p0i16(i16* %ptr)
130
137
; CHECK: [[OLDVAL:%.*]] = trunc i32 %1 to i16
131
138
; 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:.*]]
133
143
134
144
; CHECK: [[TRY_STORE]]:
145
+ ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i16 [ [[OLDVAL]], %[[FENCED_STORE]] ]
135
146
; CHECK: [[NEWVAL32:%.*]] = zext i16 %newval to i32
136
147
; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.stlex.p0i16(i32 [[NEWVAL32]], i16* %ptr)
137
148
; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0
@@ -142,16 +153,20 @@ define i16 @test_cmpxchg_i16_seqcst_monotonic(i16* %ptr, i16 %desired, i16 %newv
142
153
; CHECK: br label %[[DONE:.*]]
143
154
144
155
; CHECK: [[NO_STORE_BB]]:
156
+ ; The PHI is not required.
157
+ ; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i16 [ [[OLDVAL]], %[[LOOP]] ]
145
158
; CHECK-NEXT: call void @llvm.arm.clrex()
146
159
; CHECK-NEXT: br label %[[FAILURE_BB:.*]]
147
160
148
161
; CHECK: [[FAILURE_BB]]:
162
+ ; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i16 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ]
149
163
; CHECK-NOT: fence
150
164
; CHECK: br label %[[DONE]]
151
165
152
166
; CHECK: [[DONE]]:
167
+ ; CHECK: [[LOADED_EXIT:%.*]] = phi i16 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ]
153
168
; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
154
- ; CHECK: ret i16 [[OLDVAL ]]
169
+ ; CHECK: ret i16 [[LOADED_EXIT ]]
155
170
156
171
%pairold = cmpxchg i16* %ptr , i16 %desired , i16 %newval seq_cst monotonic
157
172
%old = extractvalue { i16 , i1 } %pairold , 0
@@ -166,9 +181,13 @@ define i32 @test_cmpxchg_i32_acquire_acquire(i32* %ptr, i32 %desired, i32 %newva
166
181
; CHECK: [[LOOP]]:
167
182
; CHECK: [[OLDVAL:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* %ptr)
168
183
; 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:.*]]
170
188
171
189
; CHECK: [[TRY_STORE]]:
190
+ ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[OLDVAL]], %[[FENCED_STORE]] ]
172
191
; CHECK: [[TRYAGAIN:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 %newval, i32* %ptr)
173
192
; CHECK: [[TST:%.*]] = icmp eq i32 [[TRYAGAIN]], 0
174
193
; 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
178
197
; CHECK: br label %[[DONE:.*]]
179
198
180
199
; CHECK: [[NO_STORE_BB]]:
200
+ ; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[OLDVAL]], %[[LOOP]] ]
181
201
; CHECK-NEXT: call void @llvm.arm.clrex()
182
202
; CHECK-NEXT: br label %[[FAILURE_BB:.*]]
183
203
184
204
; CHECK: [[FAILURE_BB]]:
205
+ ; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ]
185
206
; CHECK-NOT: fence_cst
186
207
; CHECK: br label %[[DONE]]
187
208
188
209
; CHECK: [[DONE]]:
210
+ ; CHECK: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ]
189
211
; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
190
- ; CHECK: ret i32 [[OLDVAL ]]
212
+ ; CHECK: ret i32 [[LOADED_EXIT ]]
191
213
192
214
%pairold = cmpxchg i32* %ptr , i32 %desired , i32 %newval acquire acquire
193
215
%old = extractvalue { i32 , i1 } %pairold , 0
@@ -209,9 +231,13 @@ define i64 @test_cmpxchg_i64_monotonic_monotonic(i64* %ptr, i64 %desired, i64 %n
209
231
; CHECK: [[HI64:%.*]] = shl i64 [[HI64_TMP]], 32
210
232
; CHECK: [[OLDVAL:%.*]] = or i64 [[LO64]], [[HI64]]
211
233
; 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:.*]]
213
238
214
239
; CHECK: [[TRY_STORE]]:
240
+ ; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i64 [ [[OLDVAL]], %[[FENCED_STORE]] ]
215
241
; CHECK: [[NEWLO:%.*]] = trunc i64 %newval to i32
216
242
; CHECK: [[NEWHI_TMP:%.*]] = lshr i64 %newval, 32
217
243
; 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
225
251
; CHECK: br label %[[DONE:.*]]
226
252
227
253
; CHECK: [[NO_STORE_BB]]:
254
+ ; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i64 [ [[OLDVAL]], %[[LOOP]] ]
228
255
; CHECK-NEXT: call void @llvm.arm.clrex()
229
256
; CHECK-NEXT: br label %[[FAILURE_BB:.*]]
230
257
231
258
; CHECK: [[FAILURE_BB]]:
259
+ ; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i64 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ]
232
260
; CHECK-NOT: fence_cst
233
261
; CHECK: br label %[[DONE]]
234
262
235
263
; CHECK: [[DONE]]:
264
+ ; CHECK: [[LOADED_EXIT:%.*]] = phi i64 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ]
236
265
; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ]
237
- ; CHECK: ret i64 [[OLDVAL ]]
266
+ ; CHECK: ret i64 [[LOADED_EXIT ]]
238
267
239
268
%pairold = cmpxchg i64* %ptr , i64 %desired , i64 %newval monotonic monotonic
240
269
%old = extractvalue { i64 , i1 } %pairold , 0
0 commit comments