1; RUN: llc < %s -march=sparcv9 -verify-machineinstrs | FileCheck %s
2
3; CHECK-LABEL: test_atomic_i32
4; CHECK:       ld [%o0]
5; CHECK:       membar
6; CHECK:       ld [%o1]
7; CHECK:       membar
8; CHECK:       membar
9; CHECK:       st {{.+}}, [%o2]
10define i32 @test_atomic_i32(i32* %ptr1, i32* %ptr2, i32* %ptr3) {
11entry:
12  %0 = load atomic i32* %ptr1 acquire, align 8
13  %1 = load atomic i32* %ptr2 acquire, align 8
14  %2 = add i32 %0, %1
15  store atomic i32 %2, i32* %ptr3 release, align 8
16  ret i32 %2
17}
18
19; CHECK-LABEL: test_atomic_i64
20; CHECK:       ldx [%o0]
21; CHECK:       membar
22; CHECK:       ldx [%o1]
23; CHECK:       membar
24; CHECK:       membar
25; CHECK:       stx {{.+}}, [%o2]
26define i64 @test_atomic_i64(i64* %ptr1, i64* %ptr2, i64* %ptr3) {
27entry:
28  %0 = load atomic i64* %ptr1 acquire, align 8
29  %1 = load atomic i64* %ptr2 acquire, align 8
30  %2 = add i64 %0, %1
31  store atomic i64 %2, i64* %ptr3 release, align 8
32  ret i64 %2
33}
34
35; CHECK-LABEL: test_cmpxchg_i32
36; CHECK:       or  %g0, 123, [[R:%[gilo][0-7]]]
37; CHECK:       cas [%o1], %o0, [[R]]
38
39define i32 @test_cmpxchg_i32(i32 %a, i32* %ptr) {
40entry:
41  %b = cmpxchg i32* %ptr, i32 %a, i32 123 monotonic
42  ret i32 %b
43}
44
45; CHECK-LABEL: test_cmpxchg_i64
46; CHECK:       or  %g0, 123, [[R:%[gilo][0-7]]]
47; CHECK:       casx [%o1], %o0, [[R]]
48
49define i64 @test_cmpxchg_i64(i64 %a, i64* %ptr) {
50entry:
51  %b = cmpxchg i64* %ptr, i64 %a, i64 123 monotonic
52  ret i64 %b
53}
54
55; CHECK-LABEL: test_swap_i32
56; CHECK:       or  %g0, 42, [[R:%[gilo][0-7]]]
57; CHECK:       swap [%o1], [[R]]
58
59define i32 @test_swap_i32(i32 %a, i32* %ptr) {
60entry:
61  %b = atomicrmw xchg i32* %ptr, i32 42 monotonic
62  ret i32 %b
63}
64
65; CHECK-LABEL: test_swap_i64
66; CHECK:       casx [%o1],
67
68define i64 @test_swap_i64(i64 %a, i64* %ptr) {
69entry:
70  %b = atomicrmw xchg i64* %ptr, i64 42 monotonic
71  ret i64 %b
72}
73
74; CHECK-LABEL: test_load_add_32
75; CHECK: membar
76; CHECK: add [[V:%[gilo][0-7]]], %o1, [[U:%[gilo][0-7]]]
77; CHECK: cas [%o0], [[V]], [[U]]
78; CHECK: membar
79define zeroext i32 @test_load_add_32(i32* %p, i32 zeroext %v) {
80entry:
81  %0 = atomicrmw add i32* %p, i32 %v seq_cst
82  ret i32 %0
83}
84
85; CHECK-LABEL: test_load_sub_64
86; CHECK: membar
87; CHECK: sub
88; CHECK: casx [%o0]
89; CHECK: membar
90define zeroext i64 @test_load_sub_64(i64* %p, i64 zeroext %v) {
91entry:
92  %0 = atomicrmw sub i64* %p, i64 %v seq_cst
93  ret i64 %0
94}
95
96; CHECK-LABEL: test_load_xor_32
97; CHECK: membar
98; CHECK: xor
99; CHECK: cas [%o0]
100; CHECK: membar
101define zeroext i32 @test_load_xor_32(i32* %p, i32 zeroext %v) {
102entry:
103  %0 = atomicrmw xor i32* %p, i32 %v seq_cst
104  ret i32 %0
105}
106
107; CHECK-LABEL: test_load_and_32
108; CHECK: membar
109; CHECK: and
110; CHECK-NOT: xor
111; CHECK: cas [%o0]
112; CHECK: membar
113define zeroext i32 @test_load_and_32(i32* %p, i32 zeroext %v) {
114entry:
115  %0 = atomicrmw and i32* %p, i32 %v seq_cst
116  ret i32 %0
117}
118
119; CHECK-LABEL: test_load_nand_32
120; CHECK: membar
121; CHECK: and
122; CHECK: xor
123; CHECK: cas [%o0]
124; CHECK: membar
125define zeroext i32 @test_load_nand_32(i32* %p, i32 zeroext %v) {
126entry:
127  %0 = atomicrmw nand i32* %p, i32 %v seq_cst
128  ret i32 %0
129}
130
131; CHECK-LABEL: test_load_max_64
132; CHECK: membar
133; CHECK: cmp
134; CHECK: movg %xcc
135; CHECK: casx [%o0]
136; CHECK: membar
137define zeroext i64 @test_load_max_64(i64* %p, i64 zeroext %v) {
138entry:
139  %0 = atomicrmw max i64* %p, i64 %v seq_cst
140  ret i64 %0
141}
142
143; CHECK-LABEL: test_load_umin_32
144; CHECK: membar
145; CHECK: cmp
146; CHECK: movleu %icc
147; CHECK: cas [%o0]
148; CHECK: membar
149define zeroext i32 @test_load_umin_32(i32* %p, i32 zeroext %v) {
150entry:
151  %0 = atomicrmw umin i32* %p, i32 %v seq_cst
152  ret i32 %0
153}
154