xref: /llvm-project/clang/test/CodeGenOpenCL/atomic-builtins-default-to-device-scope.cl (revision 29441e4f5fa5f5c7709f7cf180815ba97f611297)
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -O3 -o - -triple=amdgcn-amd-amdhsa \
3// RUN:   | FileCheck %s --check-prefix=AMDGCN
4// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -O3 -o - -triple=spirv64-unknown-unknown \
5// RUN:   | FileCheck %s --check-prefix=SPIRV
6
7// AMDGCN-LABEL: define dso_local i32 @load(
8// AMDGCN-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
9// AMDGCN-NEXT:  [[ENTRY:.*:]]
10// AMDGCN-NEXT:    [[TMP0:%.*]] = load atomic i32, ptr [[P]] syncscope("agent") seq_cst, align 4
11// AMDGCN-NEXT:    ret i32 [[TMP0]]
12//
13// SPIRV-LABEL: define spir_func i32 @load(
14// SPIRV-SAME: ptr addrspace(4) noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
15// SPIRV-NEXT:  [[ENTRY:.*:]]
16// SPIRV-NEXT:    [[TMP0:%.*]] = load atomic i32, ptr addrspace(4) [[P]] syncscope("device") seq_cst, align 4
17// SPIRV-NEXT:    ret i32 [[TMP0]]
18//
19int load(int *p) { return __atomic_load_n(p, __ATOMIC_SEQ_CST); }
20// AMDGCN-LABEL: define dso_local void @store(
21// AMDGCN-SAME: ptr noundef writeonly captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
22// AMDGCN-NEXT:  [[ENTRY:.*:]]
23// AMDGCN-NEXT:    store atomic i32 [[X]], ptr [[P]] syncscope("agent") seq_cst, align 4
24// AMDGCN-NEXT:    ret void
25//
26// SPIRV-LABEL: define spir_func void @store(
27// SPIRV-SAME: ptr addrspace(4) noundef writeonly captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
28// SPIRV-NEXT:  [[ENTRY:.*:]]
29// SPIRV-NEXT:    store atomic i32 [[X]], ptr addrspace(4) [[P]] syncscope("device") seq_cst, align 4
30// SPIRV-NEXT:    ret void
31//
32void store(int *p, int x) { return __atomic_store_n(p, x, __ATOMIC_SEQ_CST); }
33// AMDGCN-LABEL: define dso_local i32 @add(
34// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
35// AMDGCN-NEXT:  [[ENTRY:.*:]]
36// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw add ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4
37// AMDGCN-NEXT:    ret i32 [[TMP0]]
38//
39// SPIRV-LABEL: define spir_func i32 @add(
40// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
41// SPIRV-NEXT:  [[ENTRY:.*:]]
42// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw add ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4
43// SPIRV-NEXT:    ret i32 [[TMP0]]
44//
45int add(int *p, int x) { return __atomic_fetch_add(p, x, __ATOMIC_SEQ_CST); }
46// AMDGCN-LABEL: define dso_local float @fadd(
47// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
48// AMDGCN-NEXT:  [[ENTRY:.*:]]
49// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw fadd ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 4
50// AMDGCN-NEXT:    ret float [[TMP0]]
51//
52// SPIRV-LABEL: define spir_func float @fadd(
53// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
54// SPIRV-NEXT:  [[ENTRY:.*:]]
55// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw fadd ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 4
56// SPIRV-NEXT:    ret float [[TMP0]]
57//
58float fadd(float *p, float x) { return __atomic_fetch_add(p, x, __ATOMIC_SEQ_CST); }
59// AMDGCN-LABEL: define dso_local i32 @sub(
60// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
61// AMDGCN-NEXT:  [[ENTRY:.*:]]
62// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw sub ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4
63// AMDGCN-NEXT:    ret i32 [[TMP0]]
64//
65// SPIRV-LABEL: define spir_func i32 @sub(
66// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
67// SPIRV-NEXT:  [[ENTRY:.*:]]
68// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw sub ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4
69// SPIRV-NEXT:    ret i32 [[TMP0]]
70//
71int sub(int *p, int x) { return __atomic_fetch_sub(p, x, __ATOMIC_SEQ_CST); }
72// AMDGCN-LABEL: define dso_local float @fsub(
73// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
74// AMDGCN-NEXT:  [[ENTRY:.*:]]
75// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw fsub ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 4
76// AMDGCN-NEXT:    ret float [[TMP0]]
77//
78// SPIRV-LABEL: define spir_func float @fsub(
79// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
80// SPIRV-NEXT:  [[ENTRY:.*:]]
81// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw fsub ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 4
82// SPIRV-NEXT:    ret float [[TMP0]]
83//
84float fsub(float *p, float x) { return __atomic_fetch_sub(p, x, __ATOMIC_SEQ_CST); }
85// AMDGCN-LABEL: define dso_local i32 @and(
86// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
87// AMDGCN-NEXT:  [[ENTRY:.*:]]
88// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw and ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4
89// AMDGCN-NEXT:    ret i32 [[TMP0]]
90//
91// SPIRV-LABEL: define spir_func i32 @and(
92// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
93// SPIRV-NEXT:  [[ENTRY:.*:]]
94// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw and ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4
95// SPIRV-NEXT:    ret i32 [[TMP0]]
96//
97int and(int *p, int x) { return __atomic_fetch_and(p, x, __ATOMIC_SEQ_CST); }
98// AMDGCN-LABEL: define dso_local i32 @nand(
99// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
100// AMDGCN-NEXT:  [[ENTRY:.*:]]
101// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw nand ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4
102// AMDGCN-NEXT:    ret i32 [[TMP0]]
103//
104// SPIRV-LABEL: define spir_func i32 @nand(
105// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
106// SPIRV-NEXT:  [[ENTRY:.*:]]
107// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw nand ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4
108// SPIRV-NEXT:    ret i32 [[TMP0]]
109//
110int nand(int *p, int x) { return __atomic_fetch_nand(p, x, __ATOMIC_SEQ_CST); }
111// AMDGCN-LABEL: define dso_local i32 @or(
112// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
113// AMDGCN-NEXT:  [[ENTRY:.*:]]
114// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw or ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4
115// AMDGCN-NEXT:    ret i32 [[TMP0]]
116//
117// SPIRV-LABEL: define spir_func i32 @or(
118// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
119// SPIRV-NEXT:  [[ENTRY:.*:]]
120// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw or ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4
121// SPIRV-NEXT:    ret i32 [[TMP0]]
122//
123int or(int *p, int x) { return __atomic_fetch_or(p, x, __ATOMIC_SEQ_CST); }
124// AMDGCN-LABEL: define dso_local i32 @xor(
125// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
126// AMDGCN-NEXT:  [[ENTRY:.*:]]
127// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw xor ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4
128// AMDGCN-NEXT:    ret i32 [[TMP0]]
129//
130// SPIRV-LABEL: define spir_func i32 @xor(
131// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
132// SPIRV-NEXT:  [[ENTRY:.*:]]
133// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw xor ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4
134// SPIRV-NEXT:    ret i32 [[TMP0]]
135//
136int xor(int *p, int x) { return __atomic_fetch_xor(p, x, __ATOMIC_SEQ_CST); }
137// AMDGCN-LABEL: define dso_local i32 @min(
138// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
139// AMDGCN-NEXT:  [[ENTRY:.*:]]
140// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw min ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4
141// AMDGCN-NEXT:    ret i32 [[TMP0]]
142//
143// SPIRV-LABEL: define spir_func i32 @min(
144// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
145// SPIRV-NEXT:  [[ENTRY:.*:]]
146// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw min ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4
147// SPIRV-NEXT:    ret i32 [[TMP0]]
148//
149int min(int *p, int x) { return __atomic_fetch_min(p, x, __ATOMIC_SEQ_CST); }
150// AMDGCN-LABEL: define dso_local float @fmin(
151// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
152// AMDGCN-NEXT:  [[ENTRY:.*:]]
153// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw fmin ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 4
154// AMDGCN-NEXT:    ret float [[TMP0]]
155//
156// SPIRV-LABEL: define spir_func float @fmin(
157// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
158// SPIRV-NEXT:  [[ENTRY:.*:]]
159// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw fmin ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 4
160// SPIRV-NEXT:    ret float [[TMP0]]
161//
162float fmin(float *p, float x) { return __atomic_fetch_min(p, x, __ATOMIC_SEQ_CST); }
163// AMDGCN-LABEL: define dso_local i32 @max(
164// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
165// AMDGCN-NEXT:  [[ENTRY:.*:]]
166// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw max ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4
167// AMDGCN-NEXT:    ret i32 [[TMP0]]
168//
169// SPIRV-LABEL: define spir_func i32 @max(
170// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
171// SPIRV-NEXT:  [[ENTRY:.*:]]
172// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw max ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4
173// SPIRV-NEXT:    ret i32 [[TMP0]]
174//
175int max(int *p, int x) { return __atomic_fetch_max(p, x, __ATOMIC_SEQ_CST); }
176// AMDGCN-LABEL: define dso_local float @fmax(
177// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
178// AMDGCN-NEXT:  [[ENTRY:.*:]]
179// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw fmax ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 4
180// AMDGCN-NEXT:    ret float [[TMP0]]
181//
182// SPIRV-LABEL: define spir_func float @fmax(
183// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
184// SPIRV-NEXT:  [[ENTRY:.*:]]
185// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw fmax ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 4
186// SPIRV-NEXT:    ret float [[TMP0]]
187//
188float fmax(float *p, float x) { return __atomic_fetch_max(p, x, __ATOMIC_SEQ_CST); }
189// AMDGCN-LABEL: define dso_local i32 @xchg(
190// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
191// AMDGCN-NEXT:  [[ENTRY:.*:]]
192// AMDGCN-NEXT:    [[TMP0:%.*]] = atomicrmw xchg ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4
193// AMDGCN-NEXT:    ret i32 [[TMP0]]
194//
195// SPIRV-LABEL: define spir_func i32 @xchg(
196// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
197// SPIRV-NEXT:  [[ENTRY:.*:]]
198// SPIRV-NEXT:    [[TMP0:%.*]] = atomicrmw xchg ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4
199// SPIRV-NEXT:    ret i32 [[TMP0]]
200//
201int xchg(int *p, int x) { return __atomic_exchange_n(p, x, __ATOMIC_SEQ_CST); }
202// AMDGCN-LABEL: define dso_local range(i32 0, 2) i32 @cmpxchg(
203// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
204// AMDGCN-NEXT:  [[ENTRY:.*:]]
205// AMDGCN-NEXT:    [[TMP0:%.*]] = cmpxchg ptr [[P]], i32 [[X]], i32 [[Y]] syncscope("agent") seq_cst seq_cst, align 4
206// AMDGCN-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
207// AMDGCN-NEXT:    [[CONV:%.*]] = zext i1 [[TMP1]] to i32
208// AMDGCN-NEXT:    ret i32 [[CONV]]
209//
210// SPIRV-LABEL: define spir_func range(i32 0, 2) i32 @cmpxchg(
211// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
212// SPIRV-NEXT:  [[ENTRY:.*:]]
213// SPIRV-NEXT:    [[TMP0:%.*]] = cmpxchg ptr addrspace(4) [[P]], i32 [[X]], i32 [[Y]] syncscope("device") seq_cst seq_cst, align 4
214// SPIRV-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
215// SPIRV-NEXT:    [[CONV:%.*]] = zext i1 [[TMP1]] to i32
216// SPIRV-NEXT:    ret i32 [[CONV]]
217//
218int cmpxchg(int *p, int x, int y) { return __atomic_compare_exchange(p, &x, &y, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
219// AMDGCN-LABEL: define dso_local range(i32 0, 2) i32 @cmpxchg_weak(
220// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
221// AMDGCN-NEXT:  [[ENTRY:.*:]]
222// AMDGCN-NEXT:    [[TMP0:%.*]] = cmpxchg weak ptr [[P]], i32 [[X]], i32 [[Y]] syncscope("agent") seq_cst seq_cst, align 4
223// AMDGCN-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
224// AMDGCN-NEXT:    [[CONV:%.*]] = zext i1 [[TMP1]] to i32
225// AMDGCN-NEXT:    ret i32 [[CONV]]
226//
227// SPIRV-LABEL: define spir_func range(i32 0, 2) i32 @cmpxchg_weak(
228// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
229// SPIRV-NEXT:  [[ENTRY:.*:]]
230// SPIRV-NEXT:    [[TMP0:%.*]] = cmpxchg weak ptr addrspace(4) [[P]], i32 [[X]], i32 [[Y]] syncscope("device") seq_cst seq_cst, align 4
231// SPIRV-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
232// SPIRV-NEXT:    [[CONV:%.*]] = zext i1 [[TMP1]] to i32
233// SPIRV-NEXT:    ret i32 [[CONV]]
234//
235int cmpxchg_weak(int *p, int x, int y) { return __atomic_compare_exchange(p, &x, &y, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
236