xref: /llvm-project/llvm/test/CodeGen/NVPTX/atomics.ll (revision b279f6b098d3849f7f1c1f539b108307d5f8ae2d)
1; RUN: llc < %s -mtriple=nvptx64 -mcpu=sm_32 | FileCheck %s
2; RUN: %if ptxas %{ llc < %s -mtriple=nvptx64 -mcpu=sm_32 | %ptxas-verify %}
3
4
5; CHECK-LABEL: atom0
6define i32 @atom0(ptr %addr, i32 %val) {
7; CHECK: atom.add.u32
8  %ret = atomicrmw add ptr %addr, i32 %val seq_cst
9  ret i32 %ret
10}
11
12; CHECK-LABEL: atom1
13define i64 @atom1(ptr %addr, i64 %val) {
14; CHECK: atom.add.u64
15  %ret = atomicrmw add ptr %addr, i64 %val seq_cst
16  ret i64 %ret
17}
18
19; CHECK-LABEL: atom2
20define i32 @atom2(ptr %subr, i32 %val) {
21; CHECK: neg.s32
22; CHECK: atom.add.u32
23  %ret = atomicrmw sub ptr %subr, i32 %val seq_cst
24  ret i32 %ret
25}
26
27; CHECK-LABEL: atom3
28define i64 @atom3(ptr %subr, i64 %val) {
29; CHECK: neg.s64
30; CHECK: atom.add.u64
31  %ret = atomicrmw sub ptr %subr, i64 %val seq_cst
32  ret i64 %ret
33}
34
35; CHECK-LABEL: atom4
36define i32 @atom4(ptr %subr, i32 %val) {
37; CHECK: atom.and.b32
38  %ret = atomicrmw and ptr %subr, i32 %val seq_cst
39  ret i32 %ret
40}
41
42; CHECK-LABEL: atom5
43define i64 @atom5(ptr %subr, i64 %val) {
44; CHECK: atom.and.b64
45  %ret = atomicrmw and ptr %subr, i64 %val seq_cst
46  ret i64 %ret
47}
48
49;; NAND not yet supported
50;define i32 @atom6(ptr %subr, i32 %val) {
51;  %ret = atomicrmw nand ptr %subr, i32 %val seq_cst
52;  ret i32 %ret
53;}
54
55;define i64 @atom7(ptr %subr, i64 %val) {
56;  %ret = atomicrmw nand ptr %subr, i64 %val seq_cst
57;  ret i64 %ret
58;}
59
60; CHECK-LABEL: atom8
61define i32 @atom8(ptr %subr, i32 %val) {
62; CHECK: atom.or.b32
63  %ret = atomicrmw or ptr %subr, i32 %val seq_cst
64  ret i32 %ret
65}
66
67; CHECK-LABEL: atom9
68define i64 @atom9(ptr %subr, i64 %val) {
69; CHECK: atom.or.b64
70  %ret = atomicrmw or ptr %subr, i64 %val seq_cst
71  ret i64 %ret
72}
73
74; CHECK-LABEL: atom10
75define i32 @atom10(ptr %subr, i32 %val) {
76; CHECK: atom.xor.b32
77  %ret = atomicrmw xor ptr %subr, i32 %val seq_cst
78  ret i32 %ret
79}
80
81; CHECK-LABEL: atom11
82define i64 @atom11(ptr %subr, i64 %val) {
83; CHECK: atom.xor.b64
84  %ret = atomicrmw xor ptr %subr, i64 %val seq_cst
85  ret i64 %ret
86}
87
88; CHECK-LABEL: atom12
89define i32 @atom12(ptr %subr, i32 %val) {
90; CHECK: atom.max.s32
91  %ret = atomicrmw max ptr %subr, i32 %val seq_cst
92  ret i32 %ret
93}
94
95; CHECK-LABEL: atom13
96define i64 @atom13(ptr %subr, i64 %val) {
97; CHECK: atom.max.s64
98  %ret = atomicrmw max ptr %subr, i64 %val seq_cst
99  ret i64 %ret
100}
101
102; CHECK-LABEL: atom14
103define i32 @atom14(ptr %subr, i32 %val) {
104; CHECK: atom.min.s32
105  %ret = atomicrmw min ptr %subr, i32 %val seq_cst
106  ret i32 %ret
107}
108
109; CHECK-LABEL: atom15
110define i64 @atom15(ptr %subr, i64 %val) {
111; CHECK: atom.min.s64
112  %ret = atomicrmw min ptr %subr, i64 %val seq_cst
113  ret i64 %ret
114}
115
116; CHECK-LABEL: atom16
117define i32 @atom16(ptr %subr, i32 %val) {
118; CHECK: atom.max.u32
119  %ret = atomicrmw umax ptr %subr, i32 %val seq_cst
120  ret i32 %ret
121}
122
123; CHECK-LABEL: atom17
124define i64 @atom17(ptr %subr, i64 %val) {
125; CHECK: atom.max.u64
126  %ret = atomicrmw umax ptr %subr, i64 %val seq_cst
127  ret i64 %ret
128}
129
130; CHECK-LABEL: atom18
131define i32 @atom18(ptr %subr, i32 %val) {
132; CHECK: atom.min.u32
133  %ret = atomicrmw umin ptr %subr, i32 %val seq_cst
134  ret i32 %ret
135}
136
137; CHECK-LABEL: atom19
138define i64 @atom19(ptr %subr, i64 %val) {
139; CHECK: atom.min.u64
140  %ret = atomicrmw umin ptr %subr, i64 %val seq_cst
141  ret i64 %ret
142}
143
144declare float @llvm.nvvm.atomic.load.add.f32.p0(ptr %addr, float %val)
145
146; CHECK-LABEL: atomic_add_f32_generic
147define float @atomic_add_f32_generic(ptr %addr, float %val) {
148; CHECK: atom.add.f32
149  %ret = call float @llvm.nvvm.atomic.load.add.f32.p0(ptr %addr, float %val)
150  ret float %ret
151}
152
153declare float @llvm.nvvm.atomic.load.add.f32.p1(ptr addrspace(1) %addr, float %val)
154
155; CHECK-LABEL: atomic_add_f32_addrspace1
156define float @atomic_add_f32_addrspace1(ptr addrspace(1) %addr, float %val) {
157; CHECK: atom.global.add.f32
158  %ret = call float @llvm.nvvm.atomic.load.add.f32.p1(ptr addrspace(1) %addr, float %val)
159  ret float %ret
160}
161
162declare float @llvm.nvvm.atomic.load.add.f32.p3(ptr addrspace(3) %addr, float %val)
163
164; CHECK-LABEL: atomic_add_f32_addrspace3
165define float @atomic_add_f32_addrspace3(ptr addrspace(3) %addr, float %val) {
166; CHECK: atom.shared.add.f32
167  %ret = call float @llvm.nvvm.atomic.load.add.f32.p3(ptr addrspace(3) %addr, float %val)
168  ret float %ret
169}
170
171; CHECK-LABEL: atomicrmw_add_f32_generic
172define float @atomicrmw_add_f32_generic(ptr %addr, float %val) {
173; CHECK: atom.add.f32
174  %ret = atomicrmw fadd ptr %addr, float %val seq_cst
175  ret float %ret
176}
177
178; CHECK-LABEL: atomicrmw_add_f16_generic
179define half @atomicrmw_add_f16_generic(ptr %addr, half %val) {
180; CHECK: atom.cas
181  %ret = atomicrmw fadd ptr %addr, half %val seq_cst
182  ret half %ret
183}
184
185; CHECK-LABEL: atomicrmw_add_f32_addrspace1
186define float @atomicrmw_add_f32_addrspace1(ptr addrspace(1) %addr, float %val) {
187; CHECK: atom.global.add.f32
188  %ret = atomicrmw fadd ptr addrspace(1) %addr, float %val seq_cst
189  ret float %ret
190}
191
192; CHECK-LABEL: atomicrmw_add_f32_addrspace3
193define float @atomicrmw_add_f32_addrspace3(ptr addrspace(3) %addr, float %val) {
194; CHECK: atom.shared.add.f32
195  %ret = atomicrmw fadd ptr addrspace(3) %addr, float %val seq_cst
196  ret float %ret
197}
198
199; CHECK-LABEL: atomic_cmpxchg_i32
200define i32 @atomic_cmpxchg_i32(ptr %addr, i32 %cmp, i32 %new) {
201; CHECK: atom.cas.b32
202  %pairold = cmpxchg ptr %addr, i32 %cmp, i32 %new seq_cst seq_cst
203  ret i32 %new
204}
205
206; CHECK-LABEL: atomic_cmpxchg_i64
207define i64 @atomic_cmpxchg_i64(ptr %addr, i64 %cmp, i64 %new) {
208; CHECK: atom.cas.b64
209  %pairold = cmpxchg ptr %addr, i64 %cmp, i64 %new seq_cst seq_cst
210  ret i64 %new
211}
212