2
2
; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-LE
3
3
; RUN: llc < %s -mtriple=armebv7 -target-abi apcs | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE
4
4
; RUN: llc < %s -mtriple=thumbebv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-BE
5
+ ; RUN: llc < %s -mtriple=armv7m--none-eabi | FileCheck %s --check-prefix=CHECK-M
6
+ ; RUN: llc < %s -mtriple=armv8m--none-eabi | FileCheck %s --check-prefix=CHECK-M
5
7
6
8
define i64 @test1 (i64* %ptr , i64 %val ) {
7
9
; CHECK-LABEL: test1:
@@ -28,6 +30,8 @@ define i64 @test1(i64* %ptr, i64 %val) {
28
30
; CHECK-THUMB: bne
29
31
; CHECK-THUMB: dmb {{ish$}}
30
32
33
+ ; CHECK-M: __sync_fetch_and_add_8
34
+
31
35
%r = atomicrmw add i64* %ptr , i64 %val seq_cst
32
36
ret i64 %r
33
37
}
@@ -57,6 +61,8 @@ define i64 @test2(i64* %ptr, i64 %val) {
57
61
; CHECK-THUMB: bne
58
62
; CHECK-THUMB: dmb {{ish$}}
59
63
64
+ ; CHECK-M: __sync_fetch_and_sub_8
65
+
60
66
%r = atomicrmw sub i64* %ptr , i64 %val seq_cst
61
67
ret i64 %r
62
68
}
@@ -86,6 +92,8 @@ define i64 @test3(i64* %ptr, i64 %val) {
86
92
; CHECK-THUMB: bne
87
93
; CHECK-THUMB: dmb {{ish$}}
88
94
95
+ ; CHECK-M: __sync_fetch_and_and_8
96
+
89
97
%r = atomicrmw and i64* %ptr , i64 %val seq_cst
90
98
ret i64 %r
91
99
}
@@ -115,6 +123,8 @@ define i64 @test4(i64* %ptr, i64 %val) {
115
123
; CHECK-THUMB: bne
116
124
; CHECK-THUMB: dmb {{ish$}}
117
125
126
+ ; CHECK-M: __sync_fetch_and_or_8
127
+
118
128
%r = atomicrmw or i64* %ptr , i64 %val seq_cst
119
129
ret i64 %r
120
130
}
@@ -144,6 +154,8 @@ define i64 @test5(i64* %ptr, i64 %val) {
144
154
; CHECK-THUMB: bne
145
155
; CHECK-THUMB: dmb {{ish$}}
146
156
157
+ ; CHECK-M: __sync_fetch_and_xor_8
158
+
147
159
%r = atomicrmw xor i64* %ptr , i64 %val seq_cst
148
160
ret i64 %r
149
161
}
@@ -165,6 +177,8 @@ define i64 @test6(i64* %ptr, i64 %val) {
165
177
; CHECK-THUMB: bne
166
178
; CHECK-THUMB: dmb {{ish$}}
167
179
180
+ ; CHECK-M: __sync_lock_test_and_set_8
181
+
168
182
%r = atomicrmw xchg i64* %ptr , i64 %val seq_cst
169
183
ret i64 %r
170
184
}
@@ -199,12 +213,15 @@ define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) {
199
213
; CHECK-THUMB: beq
200
214
; CHECK-THUMB: dmb {{ish$}}
201
215
216
+ ; CHECK-M: __sync_val_compare_and_swap_8
217
+
202
218
%pair = cmpxchg i64* %ptr , i64 %val1 , i64 %val2 seq_cst seq_cst
203
219
%r = extractvalue { i64 , i1 } %pair , 0
204
220
ret i64 %r
205
221
}
206
222
207
- ; Compiles down to a single ldrexd
223
+ ; Compiles down to a single ldrexd, except on M class devices where ldrexd
224
+ ; isn't supported.
208
225
define i64 @test8 (i64* %ptr ) {
209
226
; CHECK-LABEL: test8:
210
227
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
@@ -220,12 +237,15 @@ define i64 @test8(i64* %ptr) {
220
237
; CHECK-THUMB-NOT: strexd
221
238
; CHECK-THUMB: dmb {{ish$}}
222
239
240
+ ; CHECK-M: __sync_val_compare_and_swap_8
241
+
223
242
%r = load atomic i64 , i64* %ptr seq_cst , align 8
224
243
ret i64 %r
225
244
}
226
245
227
246
; Compiles down to atomicrmw xchg; there really isn't any more efficient
228
- ; way to write it.
247
+ ; way to write it. Except on M class devices, where ldrexd/strexd aren't
248
+ ; supported.
229
249
define void @test9 (i64* %ptr , i64 %val ) {
230
250
; CHECK-LABEL: test9:
231
251
; CHECK: dmb {{ish$}}
@@ -243,6 +263,8 @@ define void @test9(i64* %ptr, i64 %val) {
243
263
; CHECK-THUMB: bne
244
264
; CHECK-THUMB: dmb {{ish$}}
245
265
266
+ ; CHECK-M: __sync_lock_test_and_set_8
267
+
246
268
store atomic i64 %val , i64* %ptr seq_cst , align 8
247
269
ret void
248
270
}
@@ -286,6 +308,8 @@ define i64 @test10(i64* %ptr, i64 %val) {
286
308
; CHECK-THUMB: bne
287
309
; CHECK-THUMB: dmb {{ish$}}
288
310
311
+ ; CHECK-M: __sync_fetch_and_min_8
312
+
289
313
%r = atomicrmw min i64* %ptr , i64 %val seq_cst
290
314
ret i64 %r
291
315
}
@@ -329,6 +353,8 @@ define i64 @test11(i64* %ptr, i64 %val) {
329
353
; CHECK-THUMB: bne
330
354
; CHECK-THUMB: dmb {{ish$}}
331
355
356
+ ; CHECK-M: __sync_fetch_and_umin_8
357
+
332
358
%r = atomicrmw umin i64* %ptr , i64 %val seq_cst
333
359
ret i64 %r
334
360
}
@@ -372,6 +398,8 @@ define i64 @test12(i64* %ptr, i64 %val) {
372
398
; CHECK-THUMB: bne
373
399
; CHECK-THUMB: dmb {{ish$}}
374
400
401
+ ; CHECK-M: __sync_fetch_and_max_8
402
+
375
403
%r = atomicrmw max i64* %ptr , i64 %val seq_cst
376
404
ret i64 %r
377
405
}
@@ -414,6 +442,9 @@ define i64 @test13(i64* %ptr, i64 %val) {
414
442
; CHECK-THUMB: cmp
415
443
; CHECK-THUMB: bne
416
444
; CHECK-THUMB: dmb {{ish$}}
445
+
446
+ ; CHECK-M: __sync_fetch_and_umax_8
447
+
417
448
%r = atomicrmw umax i64* %ptr , i64 %val seq_cst
418
449
ret i64 %r
419
450
}
0 commit comments