xref: /llvm-project/llvm/test/CodeGen/AArch64/atomic-ops-msvc.ll (revision 7b3bbd83c0c24087072ec5b22a76799ab31f87d5)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64-windows-pc-msvc -disable-post-ra -verify-machineinstrs < %s | FileCheck %s
3
4@var8 = dso_local global i8 0
5@var16 = dso_local global i16 0
6@var32 = dso_local global i32 0
7@var64 = dso_local global i64 0
8
9define dso_local i8 @test_atomic_load_add_i8(i8 %offset) nounwind {
10; CHECK-LABEL: test_atomic_load_add_i8:
11; CHECK:       // %bb.0:
12; CHECK-NEXT:    adrp x9, var8
13; CHECK-NEXT:    add x9, x9, :lo12:var8
14; CHECK-NEXT:  .LBB0_1: // %atomicrmw.start
15; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
16; CHECK-NEXT:    ldaxrb w8, [x9]
17; CHECK-NEXT:    add w10, w8, w0
18; CHECK-NEXT:    stlxrb w11, w10, [x9]
19; CHECK-NEXT:    cbnz w11, .LBB0_1
20; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
21; CHECK-NEXT:    mov w0, w8
22; CHECK-NEXT:    dmb ish
23; CHECK-NEXT:    ret
24   %old = atomicrmw add ptr @var8, i8 %offset seq_cst
25   ret i8 %old
26}
27
28define dso_local i16 @test_atomic_load_add_i16(i16 %offset) nounwind {
29; CHECK-LABEL: test_atomic_load_add_i16:
30; CHECK:       // %bb.0:
31; CHECK-NEXT:    adrp x9, var16
32; CHECK-NEXT:    add x9, x9, :lo12:var16
33; CHECK-NEXT:  .LBB1_1: // %atomicrmw.start
34; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
35; CHECK-NEXT:    ldaxrh w8, [x9]
36; CHECK-NEXT:    add w10, w8, w0
37; CHECK-NEXT:    stxrh w11, w10, [x9]
38; CHECK-NEXT:    cbnz w11, .LBB1_1
39; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
40; CHECK-NEXT:    mov w0, w8
41; CHECK-NEXT:    ret
42   %old = atomicrmw add ptr @var16, i16 %offset acquire
43   ret i16 %old
44}
45
46define dso_local i32 @test_atomic_load_add_i32(i32 %offset) nounwind {
47; CHECK-LABEL: test_atomic_load_add_i32:
48; CHECK:       // %bb.0:
49; CHECK-NEXT:    adrp x9, var32
50; CHECK-NEXT:    add x9, x9, :lo12:var32
51; CHECK-NEXT:  .LBB2_1: // %atomicrmw.start
52; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
53; CHECK-NEXT:    ldxr w8, [x9]
54; CHECK-NEXT:    add w10, w8, w0
55; CHECK-NEXT:    stlxr w11, w10, [x9]
56; CHECK-NEXT:    cbnz w11, .LBB2_1
57; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
58; CHECK-NEXT:    mov w0, w8
59; CHECK-NEXT:    ret
60   %old = atomicrmw add ptr @var32, i32 %offset release
61   ret i32 %old
62}
63
64define dso_local i64 @test_atomic_load_add_i64(i64 %offset) nounwind {
65; CHECK-LABEL: test_atomic_load_add_i64:
66; CHECK:       // %bb.0:
67; CHECK-NEXT:    adrp x9, var64
68; CHECK-NEXT:    add x9, x9, :lo12:var64
69; CHECK-NEXT:  .LBB3_1: // %atomicrmw.start
70; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
71; CHECK-NEXT:    ldxr x8, [x9]
72; CHECK-NEXT:    add x10, x8, x0
73; CHECK-NEXT:    stxr w11, x10, [x9]
74; CHECK-NEXT:    cbnz w11, .LBB3_1
75; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
76; CHECK-NEXT:    mov x0, x8
77; CHECK-NEXT:    ret
78   %old = atomicrmw add ptr @var64, i64 %offset monotonic
79   ret i64 %old
80}
81
82define dso_local i8 @test_atomic_load_sub_i8(i8 %offset) nounwind {
83; CHECK-LABEL: test_atomic_load_sub_i8:
84; CHECK:       // %bb.0:
85; CHECK-NEXT:    adrp x9, var8
86; CHECK-NEXT:    add x9, x9, :lo12:var8
87; CHECK-NEXT:  .LBB4_1: // %atomicrmw.start
88; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
89; CHECK-NEXT:    ldxrb w8, [x9]
90; CHECK-NEXT:    sub w10, w8, w0
91; CHECK-NEXT:    stxrb w11, w10, [x9]
92; CHECK-NEXT:    cbnz w11, .LBB4_1
93; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
94; CHECK-NEXT:    mov w0, w8
95; CHECK-NEXT:    ret
96   %old = atomicrmw sub ptr @var8, i8 %offset monotonic
97   ret i8 %old
98}
99
100define dso_local i16 @test_atomic_load_sub_i16(i16 %offset) nounwind {
101; CHECK-LABEL: test_atomic_load_sub_i16:
102; CHECK:       // %bb.0:
103; CHECK-NEXT:    adrp x9, var16
104; CHECK-NEXT:    add x9, x9, :lo12:var16
105; CHECK-NEXT:  .LBB5_1: // %atomicrmw.start
106; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
107; CHECK-NEXT:    ldxrh w8, [x9]
108; CHECK-NEXT:    sub w10, w8, w0
109; CHECK-NEXT:    stlxrh w11, w10, [x9]
110; CHECK-NEXT:    cbnz w11, .LBB5_1
111; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
112; CHECK-NEXT:    mov w0, w8
113; CHECK-NEXT:    ret
114   %old = atomicrmw sub ptr @var16, i16 %offset release
115   ret i16 %old
116}
117
118define dso_local i32 @test_atomic_load_sub_i32(i32 %offset) nounwind {
119; CHECK-LABEL: test_atomic_load_sub_i32:
120; CHECK:       // %bb.0:
121; CHECK-NEXT:    adrp x9, var32
122; CHECK-NEXT:    add x9, x9, :lo12:var32
123; CHECK-NEXT:  .LBB6_1: // %atomicrmw.start
124; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
125; CHECK-NEXT:    ldaxr w8, [x9]
126; CHECK-NEXT:    sub w10, w8, w0
127; CHECK-NEXT:    stxr w11, w10, [x9]
128; CHECK-NEXT:    cbnz w11, .LBB6_1
129; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
130; CHECK-NEXT:    mov w0, w8
131; CHECK-NEXT:    ret
132   %old = atomicrmw sub ptr @var32, i32 %offset acquire
133   ret i32 %old
134}
135
136define dso_local i64 @test_atomic_load_sub_i64(i64 %offset) nounwind {
137; CHECK-LABEL: test_atomic_load_sub_i64:
138; CHECK:       // %bb.0:
139; CHECK-NEXT:    mov x8, x0
140; CHECK-NEXT:    adrp x9, var64
141; CHECK-NEXT:    add x9, x9, :lo12:var64
142; CHECK-NEXT:  .LBB7_1: // %atomicrmw.start
143; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
144; CHECK-NEXT:    ldaxr x0, [x9]
145; CHECK-NEXT:    sub x10, x0, x8
146; CHECK-NEXT:    stlxr w11, x10, [x9]
147; CHECK-NEXT:    cbnz w11, .LBB7_1
148; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
149; CHECK-NEXT:    dmb ish
150; CHECK-NEXT:    ret
151   %old = atomicrmw sub ptr @var64, i64 %offset seq_cst
152   ret i64 %old
153}
154
155define dso_local i8 @test_atomic_load_and_i8(i8 %offset) nounwind {
156; CHECK-LABEL: test_atomic_load_and_i8:
157; CHECK:       // %bb.0:
158; CHECK-NEXT:    adrp x9, var8
159; CHECK-NEXT:    add x9, x9, :lo12:var8
160; CHECK-NEXT:  .LBB8_1: // %atomicrmw.start
161; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
162; CHECK-NEXT:    ldxrb w8, [x9]
163; CHECK-NEXT:    and w10, w8, w0
164; CHECK-NEXT:    stlxrb w11, w10, [x9]
165; CHECK-NEXT:    cbnz w11, .LBB8_1
166; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
167; CHECK-NEXT:    mov w0, w8
168; CHECK-NEXT:    ret
169   %old = atomicrmw and ptr @var8, i8 %offset release
170   ret i8 %old
171}
172
173define dso_local i16 @test_atomic_load_and_i16(i16 %offset) nounwind {
174; CHECK-LABEL: test_atomic_load_and_i16:
175; CHECK:       // %bb.0:
176; CHECK-NEXT:    adrp x9, var16
177; CHECK-NEXT:    add x9, x9, :lo12:var16
178; CHECK-NEXT:  .LBB9_1: // %atomicrmw.start
179; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
180; CHECK-NEXT:    ldxrh w8, [x9]
181; CHECK-NEXT:    and w10, w8, w0
182; CHECK-NEXT:    stxrh w11, w10, [x9]
183; CHECK-NEXT:    cbnz w11, .LBB9_1
184; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
185; CHECK-NEXT:    mov w0, w8
186; CHECK-NEXT:    ret
187   %old = atomicrmw and ptr @var16, i16 %offset monotonic
188   ret i16 %old
189}
190
191define dso_local i32 @test_atomic_load_and_i32(i32 %offset) nounwind {
192; CHECK-LABEL: test_atomic_load_and_i32:
193; CHECK:       // %bb.0:
194; CHECK-NEXT:    adrp x9, var32
195; CHECK-NEXT:    add x9, x9, :lo12:var32
196; CHECK-NEXT:  .LBB10_1: // %atomicrmw.start
197; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
198; CHECK-NEXT:    ldaxr w8, [x9]
199; CHECK-NEXT:    and w10, w8, w0
200; CHECK-NEXT:    stlxr w11, w10, [x9]
201; CHECK-NEXT:    cbnz w11, .LBB10_1
202; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
203; CHECK-NEXT:    mov w0, w8
204; CHECK-NEXT:    dmb ish
205; CHECK-NEXT:    ret
206   %old = atomicrmw and ptr @var32, i32 %offset seq_cst
207   ret i32 %old
208}
209
210define dso_local i64 @test_atomic_load_and_i64(i64 %offset) nounwind {
211; CHECK-LABEL: test_atomic_load_and_i64:
212; CHECK:       // %bb.0:
213; CHECK-NEXT:    adrp x9, var64
214; CHECK-NEXT:    add x9, x9, :lo12:var64
215; CHECK-NEXT:  .LBB11_1: // %atomicrmw.start
216; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
217; CHECK-NEXT:    ldaxr x8, [x9]
218; CHECK-NEXT:    and x10, x8, x0
219; CHECK-NEXT:    stxr w11, x10, [x9]
220; CHECK-NEXT:    cbnz w11, .LBB11_1
221; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
222; CHECK-NEXT:    mov x0, x8
223; CHECK-NEXT:    ret
224   %old = atomicrmw and ptr @var64, i64 %offset acquire
225   ret i64 %old
226}
227
228define dso_local i8 @test_atomic_load_or_i8(i8 %offset) nounwind {
229; CHECK-LABEL: test_atomic_load_or_i8:
230; CHECK:       // %bb.0:
231; CHECK-NEXT:    adrp x9, var8
232; CHECK-NEXT:    add x9, x9, :lo12:var8
233; CHECK-NEXT:  .LBB12_1: // %atomicrmw.start
234; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
235; CHECK-NEXT:    ldaxrb w8, [x9]
236; CHECK-NEXT:    orr w10, w8, w0
237; CHECK-NEXT:    stlxrb w11, w10, [x9]
238; CHECK-NEXT:    cbnz w11, .LBB12_1
239; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
240; CHECK-NEXT:    mov w0, w8
241; CHECK-NEXT:    dmb ish
242; CHECK-NEXT:    ret
243   %old = atomicrmw or ptr @var8, i8 %offset seq_cst
244   ret i8 %old
245}
246
247define dso_local i16 @test_atomic_load_or_i16(i16 %offset) nounwind {
248; CHECK-LABEL: test_atomic_load_or_i16:
249; CHECK:       // %bb.0:
250; CHECK-NEXT:    adrp x9, var16
251; CHECK-NEXT:    add x9, x9, :lo12:var16
252; CHECK-NEXT:  .LBB13_1: // %atomicrmw.start
253; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
254; CHECK-NEXT:    ldxrh w8, [x9]
255; CHECK-NEXT:    orr w10, w8, w0
256; CHECK-NEXT:    stxrh w11, w10, [x9]
257; CHECK-NEXT:    cbnz w11, .LBB13_1
258; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
259; CHECK-NEXT:    mov w0, w8
260; CHECK-NEXT:    ret
261   %old = atomicrmw or ptr @var16, i16 %offset monotonic
262   ret i16 %old
263}
264
265define dso_local i32 @test_atomic_load_or_i32(i32 %offset) nounwind {
266; CHECK-LABEL: test_atomic_load_or_i32:
267; CHECK:       // %bb.0:
268; CHECK-NEXT:    adrp x9, var32
269; CHECK-NEXT:    add x9, x9, :lo12:var32
270; CHECK-NEXT:  .LBB14_1: // %atomicrmw.start
271; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
272; CHECK-NEXT:    ldaxr w8, [x9]
273; CHECK-NEXT:    orr w10, w8, w0
274; CHECK-NEXT:    stxr w11, w10, [x9]
275; CHECK-NEXT:    cbnz w11, .LBB14_1
276; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
277; CHECK-NEXT:    mov w0, w8
278; CHECK-NEXT:    ret
279   %old = atomicrmw or ptr @var32, i32 %offset acquire
280   ret i32 %old
281}
282
283define dso_local i64 @test_atomic_load_or_i64(i64 %offset) nounwind {
284; CHECK-LABEL: test_atomic_load_or_i64:
285; CHECK:       // %bb.0:
286; CHECK-NEXT:    adrp x9, var64
287; CHECK-NEXT:    add x9, x9, :lo12:var64
288; CHECK-NEXT:  .LBB15_1: // %atomicrmw.start
289; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
290; CHECK-NEXT:    ldxr x8, [x9]
291; CHECK-NEXT:    orr x10, x8, x0
292; CHECK-NEXT:    stlxr w11, x10, [x9]
293; CHECK-NEXT:    cbnz w11, .LBB15_1
294; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
295; CHECK-NEXT:    mov x0, x8
296; CHECK-NEXT:    ret
297   %old = atomicrmw or ptr @var64, i64 %offset release
298   ret i64 %old
299}
300
301define dso_local i8 @test_atomic_load_xor_i8(i8 %offset) nounwind {
302; CHECK-LABEL: test_atomic_load_xor_i8:
303; CHECK:       // %bb.0:
304; CHECK-NEXT:    adrp x9, var8
305; CHECK-NEXT:    add x9, x9, :lo12:var8
306; CHECK-NEXT:  .LBB16_1: // %atomicrmw.start
307; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
308; CHECK-NEXT:    ldaxrb w8, [x9]
309; CHECK-NEXT:    eor w10, w8, w0
310; CHECK-NEXT:    stxrb w11, w10, [x9]
311; CHECK-NEXT:    cbnz w11, .LBB16_1
312; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
313; CHECK-NEXT:    mov w0, w8
314; CHECK-NEXT:    ret
315   %old = atomicrmw xor ptr @var8, i8 %offset acquire
316   ret i8 %old
317}
318
319define dso_local i16 @test_atomic_load_xor_i16(i16 %offset) nounwind {
320; CHECK-LABEL: test_atomic_load_xor_i16:
321; CHECK:       // %bb.0:
322; CHECK-NEXT:    adrp x9, var16
323; CHECK-NEXT:    add x9, x9, :lo12:var16
324; CHECK-NEXT:  .LBB17_1: // %atomicrmw.start
325; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
326; CHECK-NEXT:    ldxrh w8, [x9]
327; CHECK-NEXT:    eor w10, w8, w0
328; CHECK-NEXT:    stlxrh w11, w10, [x9]
329; CHECK-NEXT:    cbnz w11, .LBB17_1
330; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
331; CHECK-NEXT:    mov w0, w8
332; CHECK-NEXT:    ret
333   %old = atomicrmw xor ptr @var16, i16 %offset release
334   ret i16 %old
335}
336
337define dso_local i32 @test_atomic_load_xor_i32(i32 %offset) nounwind {
338; CHECK-LABEL: test_atomic_load_xor_i32:
339; CHECK:       // %bb.0:
340; CHECK-NEXT:    adrp x9, var32
341; CHECK-NEXT:    add x9, x9, :lo12:var32
342; CHECK-NEXT:  .LBB18_1: // %atomicrmw.start
343; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
344; CHECK-NEXT:    ldaxr w8, [x9]
345; CHECK-NEXT:    eor w10, w8, w0
346; CHECK-NEXT:    stlxr w11, w10, [x9]
347; CHECK-NEXT:    cbnz w11, .LBB18_1
348; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
349; CHECK-NEXT:    mov w0, w8
350; CHECK-NEXT:    dmb ish
351; CHECK-NEXT:    ret
352   %old = atomicrmw xor ptr @var32, i32 %offset seq_cst
353   ret i32 %old
354}
355
356define dso_local i64 @test_atomic_load_xor_i64(i64 %offset) nounwind {
357; CHECK-LABEL: test_atomic_load_xor_i64:
358; CHECK:       // %bb.0:
359; CHECK-NEXT:    adrp x9, var64
360; CHECK-NEXT:    add x9, x9, :lo12:var64
361; CHECK-NEXT:  .LBB19_1: // %atomicrmw.start
362; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
363; CHECK-NEXT:    ldxr x8, [x9]
364; CHECK-NEXT:    eor x10, x8, x0
365; CHECK-NEXT:    stxr w11, x10, [x9]
366; CHECK-NEXT:    cbnz w11, .LBB19_1
367; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
368; CHECK-NEXT:    mov x0, x8
369; CHECK-NEXT:    ret
370   %old = atomicrmw xor ptr @var64, i64 %offset monotonic
371   ret i64 %old
372}
373
374define dso_local i8 @test_atomic_load_xchg_i8(i8 %offset) nounwind {
375; CHECK-LABEL: test_atomic_load_xchg_i8:
376; CHECK:       // %bb.0:
377; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
378; CHECK-NEXT:    adrp x9, var8
379; CHECK-NEXT:    add x9, x9, :lo12:var8
380; CHECK-NEXT:  .LBB20_1: // %atomicrmw.start
381; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
382; CHECK-NEXT:    ldxrb w8, [x9]
383; CHECK-NEXT:    stxrb w10, w0, [x9]
384; CHECK-NEXT:    cbnz w10, .LBB20_1
385; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
386; CHECK-NEXT:    mov w0, w8
387; CHECK-NEXT:    ret
388   %old = atomicrmw xchg ptr @var8, i8 %offset monotonic
389   ret i8 %old
390}
391
392define dso_local i16 @test_atomic_load_xchg_i16(i16 %offset) nounwind {
393; CHECK-LABEL: test_atomic_load_xchg_i16:
394; CHECK:       // %bb.0:
395; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
396; CHECK-NEXT:    adrp x9, var16
397; CHECK-NEXT:    add x9, x9, :lo12:var16
398; CHECK-NEXT:  .LBB21_1: // %atomicrmw.start
399; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
400; CHECK-NEXT:    ldaxrh w8, [x9]
401; CHECK-NEXT:    stlxrh w10, w0, [x9]
402; CHECK-NEXT:    cbnz w10, .LBB21_1
403; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
404; CHECK-NEXT:    mov w0, w8
405; CHECK-NEXT:    dmb ish
406; CHECK-NEXT:    ret
407   %old = atomicrmw xchg ptr @var16, i16 %offset seq_cst
408   ret i16 %old
409}
410
411define dso_local i32 @test_atomic_load_xchg_i32(i32 %offset) nounwind {
412; CHECK-LABEL: test_atomic_load_xchg_i32:
413; CHECK:       // %bb.0:
414; CHECK-NEXT:    mov w8, w0
415; CHECK-NEXT:    adrp x9, var32
416; CHECK-NEXT:    add x9, x9, :lo12:var32
417; CHECK-NEXT:  .LBB22_1: // %atomicrmw.start
418; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
419; CHECK-NEXT:    ldxr w0, [x9]
420; CHECK-NEXT:    stlxr w10, w8, [x9]
421; CHECK-NEXT:    cbnz w10, .LBB22_1
422; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
423; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
424; CHECK-NEXT:    ret
425   %old = atomicrmw xchg ptr @var32, i32 %offset release
426   ret i32 %old
427}
428
429define dso_local i64 @test_atomic_load_xchg_i64(i64 %offset) nounwind {
430; CHECK-LABEL: test_atomic_load_xchg_i64:
431; CHECK:       // %bb.0:
432; CHECK-NEXT:    adrp x9, var64
433; CHECK-NEXT:    add x9, x9, :lo12:var64
434; CHECK-NEXT:  .LBB23_1: // %atomicrmw.start
435; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
436; CHECK-NEXT:    ldaxr x8, [x9]
437; CHECK-NEXT:    stxr w10, x0, [x9]
438; CHECK-NEXT:    cbnz w10, .LBB23_1
439; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
440; CHECK-NEXT:    mov x0, x8
441; CHECK-NEXT:    ret
442   %old = atomicrmw xchg ptr @var64, i64 %offset acquire
443   ret i64 %old
444}
445
446
447define dso_local i8 @test_atomic_load_min_i8(i8 %offset) nounwind {
448; CHECK-LABEL: test_atomic_load_min_i8:
449; CHECK:       // %bb.0:
450; CHECK-NEXT:    adrp x9, var8
451; CHECK-NEXT:    add x9, x9, :lo12:var8
452; CHECK-NEXT:  .LBB24_1: // %atomicrmw.start
453; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
454; CHECK-NEXT:    ldaxrb w10, [x9]
455; CHECK-NEXT:    sxtb w8, w10
456; CHECK-NEXT:    cmp w8, w0, sxtb
457; CHECK-NEXT:    csel w10, w10, w0, le
458; CHECK-NEXT:    stxrb w11, w10, [x9]
459; CHECK-NEXT:    cbnz w11, .LBB24_1
460; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
461; CHECK-NEXT:    mov w0, w8
462; CHECK-NEXT:    ret
463   %old = atomicrmw min ptr @var8, i8 %offset acquire
464   ret i8 %old
465}
466
467define dso_local i16 @test_atomic_load_min_i16(i16 %offset) nounwind {
468; CHECK-LABEL: test_atomic_load_min_i16:
469; CHECK:       // %bb.0:
470; CHECK-NEXT:    adrp x9, var16
471; CHECK-NEXT:    add x9, x9, :lo12:var16
472; CHECK-NEXT:  .LBB25_1: // %atomicrmw.start
473; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
474; CHECK-NEXT:    ldxrh w10, [x9]
475; CHECK-NEXT:    sxth w8, w10
476; CHECK-NEXT:    cmp w8, w0, sxth
477; CHECK-NEXT:    csel w10, w10, w0, le
478; CHECK-NEXT:    stlxrh w11, w10, [x9]
479; CHECK-NEXT:    cbnz w11, .LBB25_1
480; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
481; CHECK-NEXT:    mov w0, w8
482; CHECK-NEXT:    ret
483   %old = atomicrmw min ptr @var16, i16 %offset release
484   ret i16 %old
485}
486
487define dso_local i32 @test_atomic_load_min_i32(i32 %offset) nounwind {
488; CHECK-LABEL: test_atomic_load_min_i32:
489; CHECK:       // %bb.0:
490; CHECK-NEXT:    adrp x9, var32
491; CHECK-NEXT:    add x9, x9, :lo12:var32
492; CHECK-NEXT:  .LBB26_1: // %atomicrmw.start
493; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
494; CHECK-NEXT:    ldxr w8, [x9]
495; CHECK-NEXT:    cmp w8, w0
496; CHECK-NEXT:    csel w10, w8, w0, le
497; CHECK-NEXT:    stxr w11, w10, [x9]
498; CHECK-NEXT:    cbnz w11, .LBB26_1
499; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
500; CHECK-NEXT:    mov w0, w8
501; CHECK-NEXT:    ret
502   %old = atomicrmw min ptr @var32, i32 %offset monotonic
503   ret i32 %old
504}
505
506define dso_local i64 @test_atomic_load_min_i64(i64 %offset) nounwind {
507; CHECK-LABEL: test_atomic_load_min_i64:
508; CHECK:       // %bb.0:
509; CHECK-NEXT:    mov x8, x0
510; CHECK-NEXT:    adrp x9, var64
511; CHECK-NEXT:    add x9, x9, :lo12:var64
512; CHECK-NEXT:  .LBB27_1: // %atomicrmw.start
513; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
514; CHECK-NEXT:    ldaxr x0, [x9]
515; CHECK-NEXT:    cmp x0, x8
516; CHECK-NEXT:    csel x10, x0, x8, le
517; CHECK-NEXT:    stlxr w11, x10, [x9]
518; CHECK-NEXT:    cbnz w11, .LBB27_1
519; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
520; CHECK-NEXT:    dmb ish
521; CHECK-NEXT:    ret
522   %old = atomicrmw min ptr @var64, i64 %offset seq_cst
523   ret i64 %old
524}
525
526define dso_local i8 @test_atomic_load_max_i8(i8 %offset) nounwind {
527; CHECK-LABEL: test_atomic_load_max_i8:
528; CHECK:       // %bb.0:
529; CHECK-NEXT:    adrp x9, var8
530; CHECK-NEXT:    add x9, x9, :lo12:var8
531; CHECK-NEXT:  .LBB28_1: // %atomicrmw.start
532; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
533; CHECK-NEXT:    ldaxrb w10, [x9]
534; CHECK-NEXT:    sxtb w8, w10
535; CHECK-NEXT:    cmp w8, w0, sxtb
536; CHECK-NEXT:    csel w10, w10, w0, gt
537; CHECK-NEXT:    stlxrb w11, w10, [x9]
538; CHECK-NEXT:    cbnz w11, .LBB28_1
539; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
540; CHECK-NEXT:    mov w0, w8
541; CHECK-NEXT:    dmb ish
542; CHECK-NEXT:    ret
543   %old = atomicrmw max ptr @var8, i8 %offset seq_cst
544   ret i8 %old
545}
546
547define dso_local i16 @test_atomic_load_max_i16(i16 %offset) nounwind {
548; CHECK-LABEL: test_atomic_load_max_i16:
549; CHECK:       // %bb.0:
550; CHECK-NEXT:    adrp x9, var16
551; CHECK-NEXT:    add x9, x9, :lo12:var16
552; CHECK-NEXT:  .LBB29_1: // %atomicrmw.start
553; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
554; CHECK-NEXT:    ldaxrh w10, [x9]
555; CHECK-NEXT:    sxth w8, w10
556; CHECK-NEXT:    cmp w8, w0, sxth
557; CHECK-NEXT:    csel w10, w10, w0, gt
558; CHECK-NEXT:    stxrh w11, w10, [x9]
559; CHECK-NEXT:    cbnz w11, .LBB29_1
560; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
561; CHECK-NEXT:    mov w0, w8
562; CHECK-NEXT:    ret
563   %old = atomicrmw max ptr @var16, i16 %offset acquire
564   ret i16 %old
565}
566
567define dso_local i32 @test_atomic_load_max_i32(i32 %offset) nounwind {
568; CHECK-LABEL: test_atomic_load_max_i32:
569; CHECK:       // %bb.0:
570; CHECK-NEXT:    adrp x9, var32
571; CHECK-NEXT:    add x9, x9, :lo12:var32
572; CHECK-NEXT:  .LBB30_1: // %atomicrmw.start
573; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
574; CHECK-NEXT:    ldxr w8, [x9]
575; CHECK-NEXT:    cmp w8, w0
576; CHECK-NEXT:    csel w10, w8, w0, gt
577; CHECK-NEXT:    stlxr w11, w10, [x9]
578; CHECK-NEXT:    cbnz w11, .LBB30_1
579; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
580; CHECK-NEXT:    mov w0, w8
581; CHECK-NEXT:    ret
582   %old = atomicrmw max ptr @var32, i32 %offset release
583   ret i32 %old
584}
585
586define dso_local i64 @test_atomic_load_max_i64(i64 %offset) nounwind {
587; CHECK-LABEL: test_atomic_load_max_i64:
588; CHECK:       // %bb.0:
589; CHECK-NEXT:    adrp x9, var64
590; CHECK-NEXT:    add x9, x9, :lo12:var64
591; CHECK-NEXT:  .LBB31_1: // %atomicrmw.start
592; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
593; CHECK-NEXT:    ldxr x8, [x9]
594; CHECK-NEXT:    cmp x8, x0
595; CHECK-NEXT:    csel x10, x8, x0, gt
596; CHECK-NEXT:    stxr w11, x10, [x9]
597; CHECK-NEXT:    cbnz w11, .LBB31_1
598; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
599; CHECK-NEXT:    mov x0, x8
600; CHECK-NEXT:    ret
601   %old = atomicrmw max ptr @var64, i64 %offset monotonic
602   ret i64 %old
603}
604
605define dso_local i8 @test_atomic_load_umin_i8(i8 %offset) nounwind {
606; CHECK-LABEL: test_atomic_load_umin_i8:
607; CHECK:       // %bb.0:
608; CHECK-NEXT:    adrp x8, var8
609; CHECK-NEXT:    add x8, x8, :lo12:var8
610; CHECK-NEXT:    and w9, w0, #0xff
611; CHECK-NEXT:  .LBB32_1: // %atomicrmw.start
612; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
613; CHECK-NEXT:    ldxrb w0, [x8]
614; CHECK-NEXT:    cmp w0, w9
615; CHECK-NEXT:    csel w10, w0, w9, ls
616; CHECK-NEXT:    stxrb w11, w10, [x8]
617; CHECK-NEXT:    cbnz w11, .LBB32_1
618; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
619; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
620; CHECK-NEXT:    ret
621   %old = atomicrmw umin ptr @var8, i8 %offset monotonic
622   ret i8 %old
623}
624
625define dso_local i16 @test_atomic_load_umin_i16(i16 %offset) nounwind {
626; CHECK-LABEL: test_atomic_load_umin_i16:
627; CHECK:       // %bb.0:
628; CHECK-NEXT:    adrp x8, var16
629; CHECK-NEXT:    add x8, x8, :lo12:var16
630; CHECK-NEXT:    and w9, w0, #0xffff
631; CHECK-NEXT:  .LBB33_1: // %atomicrmw.start
632; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
633; CHECK-NEXT:    ldaxrh w0, [x8]
634; CHECK-NEXT:    cmp w0, w9
635; CHECK-NEXT:    csel w10, w0, w9, ls
636; CHECK-NEXT:    stxrh w11, w10, [x8]
637; CHECK-NEXT:    cbnz w11, .LBB33_1
638; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
639; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
640; CHECK-NEXT:    ret
641   %old = atomicrmw umin ptr @var16, i16 %offset acquire
642   ret i16 %old
643}
644
645define dso_local i32 @test_atomic_load_umin_i32(i32 %offset) nounwind {
646; CHECK-LABEL: test_atomic_load_umin_i32:
647; CHECK:       // %bb.0:
648; CHECK-NEXT:    adrp x9, var32
649; CHECK-NEXT:    add x9, x9, :lo12:var32
650; CHECK-NEXT:  .LBB34_1: // %atomicrmw.start
651; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
652; CHECK-NEXT:    ldaxr w8, [x9]
653; CHECK-NEXT:    cmp w8, w0
654; CHECK-NEXT:    csel w10, w8, w0, ls
655; CHECK-NEXT:    stlxr w11, w10, [x9]
656; CHECK-NEXT:    cbnz w11, .LBB34_1
657; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
658; CHECK-NEXT:    mov w0, w8
659; CHECK-NEXT:    dmb ish
660; CHECK-NEXT:    ret
661   %old = atomicrmw umin ptr @var32, i32 %offset seq_cst
662   ret i32 %old
663}
664
665define dso_local i64 @test_atomic_load_umin_i64(i64 %offset) nounwind {
666; CHECK-LABEL: test_atomic_load_umin_i64:
667; CHECK:       // %bb.0:
668; CHECK-NEXT:    adrp x9, var64
669; CHECK-NEXT:    add x9, x9, :lo12:var64
670; CHECK-NEXT:  .LBB35_1: // %atomicrmw.start
671; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
672; CHECK-NEXT:    ldaxr x8, [x9]
673; CHECK-NEXT:    cmp x8, x0
674; CHECK-NEXT:    csel x10, x8, x0, ls
675; CHECK-NEXT:    stlxr w11, x10, [x9]
676; CHECK-NEXT:    cbnz w11, .LBB35_1
677; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
678; CHECK-NEXT:    mov x0, x8
679; CHECK-NEXT:    ret
680   %old = atomicrmw umin ptr @var64, i64 %offset acq_rel
681   ret i64 %old
682}
683
684define dso_local i8 @test_atomic_load_umax_i8(i8 %offset) nounwind {
685; CHECK-LABEL: test_atomic_load_umax_i8:
686; CHECK:       // %bb.0:
687; CHECK-NEXT:    adrp x8, var8
688; CHECK-NEXT:    add x8, x8, :lo12:var8
689; CHECK-NEXT:    and w9, w0, #0xff
690; CHECK-NEXT:  .LBB36_1: // %atomicrmw.start
691; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
692; CHECK-NEXT:    ldaxrb w0, [x8]
693; CHECK-NEXT:    cmp w0, w9
694; CHECK-NEXT:    csel w10, w0, w9, hi
695; CHECK-NEXT:    stlxrb w11, w10, [x8]
696; CHECK-NEXT:    cbnz w11, .LBB36_1
697; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
698; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
699; CHECK-NEXT:    ret
700   %old = atomicrmw umax ptr @var8, i8 %offset acq_rel
701   ret i8 %old
702}
703
704define dso_local i16 @test_atomic_load_umax_i16(i16 %offset) nounwind {
705; CHECK-LABEL: test_atomic_load_umax_i16:
706; CHECK:       // %bb.0:
707; CHECK-NEXT:    adrp x8, var16
708; CHECK-NEXT:    add x8, x8, :lo12:var16
709; CHECK-NEXT:    and w9, w0, #0xffff
710; CHECK-NEXT:  .LBB37_1: // %atomicrmw.start
711; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
712; CHECK-NEXT:    ldxrh w0, [x8]
713; CHECK-NEXT:    cmp w0, w9
714; CHECK-NEXT:    csel w10, w0, w9, hi
715; CHECK-NEXT:    stxrh w11, w10, [x8]
716; CHECK-NEXT:    cbnz w11, .LBB37_1
717; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
718; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
719; CHECK-NEXT:    ret
720   %old = atomicrmw umax ptr @var16, i16 %offset monotonic
721   ret i16 %old
722}
723
724define dso_local i32 @test_atomic_load_umax_i32(i32 %offset) nounwind {
725; CHECK-LABEL: test_atomic_load_umax_i32:
726; CHECK:       // %bb.0:
727; CHECK-NEXT:    adrp x9, var32
728; CHECK-NEXT:    add x9, x9, :lo12:var32
729; CHECK-NEXT:  .LBB38_1: // %atomicrmw.start
730; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
731; CHECK-NEXT:    ldaxr w8, [x9]
732; CHECK-NEXT:    cmp w8, w0
733; CHECK-NEXT:    csel w10, w8, w0, hi
734; CHECK-NEXT:    stlxr w11, w10, [x9]
735; CHECK-NEXT:    cbnz w11, .LBB38_1
736; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
737; CHECK-NEXT:    mov w0, w8
738; CHECK-NEXT:    dmb ish
739; CHECK-NEXT:    ret
740   %old = atomicrmw umax ptr @var32, i32 %offset seq_cst
741   ret i32 %old
742}
743
744define dso_local i64 @test_atomic_load_umax_i64(i64 %offset) nounwind {
745; CHECK-LABEL: test_atomic_load_umax_i64:
746; CHECK:       // %bb.0:
747; CHECK-NEXT:    adrp x9, var64
748; CHECK-NEXT:    add x9, x9, :lo12:var64
749; CHECK-NEXT:  .LBB39_1: // %atomicrmw.start
750; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
751; CHECK-NEXT:    ldxr x8, [x9]
752; CHECK-NEXT:    cmp x8, x0
753; CHECK-NEXT:    csel x10, x8, x0, hi
754; CHECK-NEXT:    stlxr w11, x10, [x9]
755; CHECK-NEXT:    cbnz w11, .LBB39_1
756; CHECK-NEXT:  // %bb.2: // %atomicrmw.end
757; CHECK-NEXT:    mov x0, x8
758; CHECK-NEXT:    ret
759   %old = atomicrmw umax ptr @var64, i64 %offset release
760   ret i64 %old
761}
762
763define dso_local i8 @test_atomic_cmpxchg_i8(i8 %wanted, i8 %new) nounwind {
764; CHECK-LABEL: test_atomic_cmpxchg_i8:
765; CHECK:       // %bb.0:
766; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
767; CHECK-NEXT:    and w8, w0, #0xff
768; CHECK-NEXT:    adrp x9, var8
769; CHECK-NEXT:    add x9, x9, :lo12:var8
770; CHECK-NEXT:  .LBB40_1: // %cmpxchg.start
771; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
772; CHECK-NEXT:    ldaxrb w0, [x9]
773; CHECK-NEXT:    cmp w0, w8
774; CHECK-NEXT:    b.ne .LBB40_4
775; CHECK-NEXT:  // %bb.2: // %cmpxchg.trystore
776; CHECK-NEXT:    // in Loop: Header=BB40_1 Depth=1
777; CHECK-NEXT:    stxrb w10, w1, [x9]
778; CHECK-NEXT:    cbnz w10, .LBB40_1
779; CHECK-NEXT:  // %bb.3: // %cmpxchg.end
780; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
781; CHECK-NEXT:    ret
782; CHECK-NEXT:  .LBB40_4: // %cmpxchg.nostore
783; CHECK-NEXT:    clrex
784; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
785; CHECK-NEXT:    ret
786   %pair = cmpxchg ptr @var8, i8 %wanted, i8 %new acquire acquire
787   %old = extractvalue { i8, i1 } %pair, 0
788   ret i8 %old
789}
790
791define dso_local i16 @test_atomic_cmpxchg_i16(i16 %wanted, i16 %new) nounwind {
792; CHECK-LABEL: test_atomic_cmpxchg_i16:
793; CHECK:       // %bb.0:
794; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
795; CHECK-NEXT:    and w8, w0, #0xffff
796; CHECK-NEXT:    adrp x9, var16
797; CHECK-NEXT:    add x9, x9, :lo12:var16
798; CHECK-NEXT:  .LBB41_1: // %cmpxchg.start
799; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
800; CHECK-NEXT:    ldaxrh w0, [x9]
801; CHECK-NEXT:    cmp w0, w8
802; CHECK-NEXT:    b.ne .LBB41_4
803; CHECK-NEXT:  // %bb.2: // %cmpxchg.trystore
804; CHECK-NEXT:    // in Loop: Header=BB41_1 Depth=1
805; CHECK-NEXT:    stlxrh w10, w1, [x9]
806; CHECK-NEXT:    cbnz w10, .LBB41_1
807; CHECK-NEXT:  // %bb.3: // %cmpxchg.success
808; CHECK-NEXT:    dmb ish
809; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
810; CHECK-NEXT:    ret
811; CHECK-NEXT:  .LBB41_4: // %cmpxchg.nostore
812; CHECK-NEXT:    clrex
813; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
814; CHECK-NEXT:    ret
815   %pair = cmpxchg ptr @var16, i16 %wanted, i16 %new seq_cst seq_cst
816   %old = extractvalue { i16, i1 } %pair, 0
817   ret i16 %old
818}
819
820define dso_local i32 @test_atomic_cmpxchg_i32(i32 %wanted, i32 %new) nounwind {
821; CHECK-LABEL: test_atomic_cmpxchg_i32:
822; CHECK:       // %bb.0:
823; CHECK-NEXT:    mov w8, w0
824; CHECK-NEXT:    adrp x9, var32
825; CHECK-NEXT:    add x9, x9, :lo12:var32
826; CHECK-NEXT:  .LBB42_1: // %cmpxchg.start
827; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
828; CHECK-NEXT:    ldxr w0, [x9]
829; CHECK-NEXT:    cmp w0, w8
830; CHECK-NEXT:    b.ne .LBB42_4
831; CHECK-NEXT:  // %bb.2: // %cmpxchg.trystore
832; CHECK-NEXT:    // in Loop: Header=BB42_1 Depth=1
833; CHECK-NEXT:    stlxr w10, w1, [x9]
834; CHECK-NEXT:    cbnz w10, .LBB42_1
835; CHECK-NEXT:  // %bb.3: // %cmpxchg.end
836; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
837; CHECK-NEXT:    ret
838; CHECK-NEXT:  .LBB42_4: // %cmpxchg.nostore
839; CHECK-NEXT:    clrex
840; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0
841; CHECK-NEXT:    ret
842   %pair = cmpxchg ptr @var32, i32 %wanted, i32 %new release monotonic
843   %old = extractvalue { i32, i1 } %pair, 0
844   ret i32 %old
845}
846
847define dso_local void @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind {
848; CHECK-LABEL: test_atomic_cmpxchg_i64:
849; CHECK:       // %bb.0:
850; CHECK-NEXT:    adrp x9, var64
851; CHECK-NEXT:    add x9, x9, :lo12:var64
852; CHECK-NEXT:  .LBB43_1: // %cmpxchg.start
853; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
854; CHECK-NEXT:    ldxr x8, [x9]
855; CHECK-NEXT:    cmp x8, x0
856; CHECK-NEXT:    b.ne .LBB43_3
857; CHECK-NEXT:  // %bb.2: // %cmpxchg.trystore
858; CHECK-NEXT:    // in Loop: Header=BB43_1 Depth=1
859; CHECK-NEXT:    stxr w10, x1, [x9]
860; CHECK-NEXT:    cbnz w10, .LBB43_1
861; CHECK-NEXT:    b .LBB43_4
862; CHECK-NEXT:  .LBB43_3: // %cmpxchg.nostore
863; CHECK-NEXT:    clrex
864; CHECK-NEXT:  .LBB43_4: // %cmpxchg.end
865; CHECK-NEXT:    adrp x9, var64
866; CHECK-NEXT:    str x8, [x9, :lo12:var64]
867; CHECK-NEXT:    ret
868   %pair = cmpxchg ptr @var64, i64 %wanted, i64 %new monotonic monotonic
869   %old = extractvalue { i64, i1 } %pair, 0
870   store i64 %old, ptr @var64
871   ret void
872}
873
874define dso_local i8 @test_atomic_load_monotonic_i8() nounwind {
875; CHECK-LABEL: test_atomic_load_monotonic_i8:
876; CHECK:       // %bb.0:
877; CHECK-NEXT:    adrp x8, var8
878; CHECK-NEXT:    ldrb w0, [x8, :lo12:var8]
879; CHECK-NEXT:    ret
880  %val = load atomic i8, ptr @var8 monotonic, align 1
881  ret i8 %val
882}
883
884define dso_local i8 @test_atomic_load_monotonic_regoff_i8(i64 %base, i64 %off) nounwind {
885; CHECK-LABEL: test_atomic_load_monotonic_regoff_i8:
886; CHECK:       // %bb.0:
887; CHECK-NEXT:    ldrb w0, [x0, x1]
888; CHECK-NEXT:    ret
889  %addr_int = add i64 %base, %off
890  %addr = inttoptr i64 %addr_int to ptr
891  %val = load atomic i8, ptr %addr monotonic, align 1
892  ret i8 %val
893}
894
895define dso_local i8 @test_atomic_load_acquire_i8() nounwind {
896; CHECK-LABEL: test_atomic_load_acquire_i8:
897; CHECK:       // %bb.0:
898; CHECK-NEXT:    adrp x8, var8
899; CHECK-NEXT:    add x8, x8, :lo12:var8
900; CHECK-NEXT:    ldarb w0, [x8]
901; CHECK-NEXT:    ret
902  %val = load atomic i8, ptr @var8 acquire, align 1
903  ret i8 %val
904}
905
906define dso_local i8 @test_atomic_load_seq_cst_i8() nounwind {
907; CHECK-LABEL: test_atomic_load_seq_cst_i8:
908; CHECK:       // %bb.0:
909; CHECK-NEXT:    adrp x8, var8
910; CHECK-NEXT:    add x8, x8, :lo12:var8
911; CHECK-NEXT:    ldarb w0, [x8]
912; CHECK-NEXT:    ret
913  %val = load atomic i8, ptr @var8 seq_cst, align 1
914  ret i8 %val
915}
916
917define dso_local i16 @test_atomic_load_monotonic_i16() nounwind {
918; CHECK-LABEL: test_atomic_load_monotonic_i16:
919; CHECK:       // %bb.0:
920; CHECK-NEXT:    adrp x8, var16
921; CHECK-NEXT:    ldrh w0, [x8, :lo12:var16]
922; CHECK-NEXT:    ret
923  %val = load atomic i16, ptr @var16 monotonic, align 2
924  ret i16 %val
925}
926
927define dso_local i32 @test_atomic_load_monotonic_regoff_i32(i64 %base, i64 %off) nounwind {
928; CHECK-LABEL: test_atomic_load_monotonic_regoff_i32:
929; CHECK:       // %bb.0:
930; CHECK-NEXT:    ldr w0, [x0, x1]
931; CHECK-NEXT:    ret
932  %addr_int = add i64 %base, %off
933  %addr = inttoptr i64 %addr_int to ptr
934  %val = load atomic i32, ptr %addr monotonic, align 4
935  ret i32 %val
936}
937
938define dso_local i64 @test_atomic_load_seq_cst_i64() nounwind {
939; CHECK-LABEL: test_atomic_load_seq_cst_i64:
940; CHECK:       // %bb.0:
941; CHECK-NEXT:    adrp x8, var64
942; CHECK-NEXT:    add x8, x8, :lo12:var64
943; CHECK-NEXT:    ldar x0, [x8]
944; CHECK-NEXT:    ret
945  %val = load atomic i64, ptr @var64 seq_cst, align 8
946  ret i64 %val
947}
948
949define dso_local void @test_atomic_store_monotonic_i8(i8 %val) nounwind {
950; CHECK-LABEL: test_atomic_store_monotonic_i8:
951; CHECK:       // %bb.0:
952; CHECK-NEXT:    adrp x8, var8
953; CHECK-NEXT:    strb w0, [x8, :lo12:var8]
954; CHECK-NEXT:    ret
955  store atomic i8 %val, ptr @var8 monotonic, align 1
956  ret void
957}
958
959define dso_local void @test_atomic_store_monotonic_regoff_i8(i64 %base, i64 %off, i8 %val) nounwind {
960; CHECK-LABEL: test_atomic_store_monotonic_regoff_i8:
961; CHECK:       // %bb.0:
962; CHECK-NEXT:    strb w2, [x0, x1]
963; CHECK-NEXT:    ret
964  %addr_int = add i64 %base, %off
965  %addr = inttoptr i64 %addr_int to ptr
966  store atomic i8 %val, ptr %addr monotonic, align 1
967  ret void
968}
969define dso_local void @test_atomic_store_release_i8(i8 %val) nounwind {
970; CHECK-LABEL: test_atomic_store_release_i8:
971; CHECK:       // %bb.0:
972; CHECK-NEXT:    adrp x8, var8
973; CHECK-NEXT:    add x8, x8, :lo12:var8
974; CHECK-NEXT:    stlrb w0, [x8]
975; CHECK-NEXT:    ret
976  store atomic i8 %val, ptr @var8 release, align 1
977  ret void
978}
979
980define dso_local void @test_atomic_store_seq_cst_i8(i8 %val) nounwind {
981; CHECK-LABEL: test_atomic_store_seq_cst_i8:
982; CHECK:       // %bb.0:
983; CHECK-NEXT:    adrp x8, var8
984; CHECK-NEXT:    add x8, x8, :lo12:var8
985; CHECK-NEXT:    stlrb w0, [x8]
986; CHECK-NEXT:    dmb ish
987; CHECK-NEXT:    ret
988  store atomic i8 %val, ptr @var8 seq_cst, align 1
989  ret void
990}
991
992define dso_local void @test_atomic_store_monotonic_i16(i16 %val) nounwind {
993; CHECK-LABEL: test_atomic_store_monotonic_i16:
994; CHECK:       // %bb.0:
995; CHECK-NEXT:    adrp x8, var16
996; CHECK-NEXT:    strh w0, [x8, :lo12:var16]
997; CHECK-NEXT:    ret
998  store atomic i16 %val, ptr @var16 monotonic, align 2
999  ret void
1000}
1001
1002define dso_local void @test_atomic_store_monotonic_regoff_i32(i64 %base, i64 %off, i32 %val) nounwind {
1003; CHECK-LABEL: test_atomic_store_monotonic_regoff_i32:
1004; CHECK:       // %bb.0:
1005; CHECK-NEXT:    str w2, [x0, x1]
1006; CHECK-NEXT:    ret
1007  %addr_int = add i64 %base, %off
1008  %addr = inttoptr i64 %addr_int to ptr
1009  store atomic i32 %val, ptr %addr monotonic, align 4
1010  ret void
1011}
1012
1013define dso_local void @test_atomic_store_release_i64(i64 %val) nounwind {
1014; CHECK-LABEL: test_atomic_store_release_i64:
1015; CHECK:       // %bb.0:
1016; CHECK-NEXT:    adrp x8, var64
1017; CHECK-NEXT:    add x8, x8, :lo12:var64
1018; CHECK-NEXT:    stlr x0, [x8]
1019; CHECK-NEXT:    ret
1020  store atomic i64 %val, ptr @var64 release, align 8
1021  ret void
1022}
1023