Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SYCL] Move SPIR-V atomic builtins declarations into clang/lib/Sema/SPIRVBuiltins.td #17471

Open
wants to merge 5 commits into
base: sycl
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions clang/lib/Sema/SPIRVBuiltins.td
Original file line number Diff line number Diff line change
Expand Up @@ -392,10 +392,13 @@ def AIGenTypeNNoScalar : GenericType<"AIGenTypeNNoScalar", TLAllInts, VecNoS
// All integer to unsigned
def AI2UGenTypeN : GenericType<"AI2UGenTypeN", TLAllUIntsTwice, VecAndScalar>;
// Signed integer
def SGenType1 : GenericType<"SGenType1", TLSignedInts, Vec1>;
def SGenTypeN : GenericType<"SGenTypeN", TLSignedInts, VecAndScalar>;
// Unsigned integer
def UGenType1 : GenericType<"UGenType1", TLUnsignedInts, Vec1>;
def UGenTypeN : GenericType<"UGenTypeN", TLUnsignedInts, VecAndScalar>;
// Float
def FGenType1 : GenericType<"FGenType1", TLFloat, Vec1>;
def FGenTypeN : GenericType<"FGenTypeN", TLFloat, VecAndScalar>;
// (u)int, (u)long, and all floats
def IntLongFloatGenType1 : GenericType<"IntLongFloatGenType1", TLIntLongFloats, Vec1>;
Expand Down Expand Up @@ -960,3 +963,67 @@ foreach name = ["GroupSMin", "GroupSMax"] in {
foreach name = ["GroupLogicalAndKHR", "GroupLogicalOrKHR"] in {
def : SPVBuiltin<name, [Bool, UInt, UInt, Bool], Attr.Convergent>;
}

// 3.56.18. Atomic Instructions

foreach AS = [GlobalAS, LocalAS, PrivateAS, GenericAS] in {
def : SPVBuiltin<
"AtomicLoad", [AGenType1, PointerType<AGenType1, AS>, Int, Int],
Attr.Convergent>;

def : SPVBuiltin<"AtomicStore",
[Void, PointerType<AGenType1, AS>, Int, Int, AGenType1],
Attr.Convergent>;

def : SPVBuiltin<"AtomicExchange",
[AGenType1, PointerType<AGenType1, AS>, Int, Int, AGenType1],
Attr.Convergent>;

foreach name = ["AtomicCompareExchange", "AtomicCompareExchangeWeak"] in {
def : SPVBuiltin<name,
[AIGenType1, PointerType<AIGenType1, AS>, Int, Int, Int,
AIGenType1, AIGenType1],
Attr.Convergent>;
}

foreach name = ["AtomicIIncrement", "AtomicIDecrement"] in {
def : SPVBuiltin<name, [AIGenType1, PointerType<AIGenType1, AS>, Int, Int],
Attr.Convergent>;
}

foreach name = ["AtomicSMin", "AtomicSMax"] in {
def : SPVBuiltin<name,
[SGenType1, PointerType<SGenType1, AS>, Int, Int,
SGenType1],
Attr.Convergent>;
}

foreach name = ["AtomicUMin", "AtomicUMax"] in {
def : SPVBuiltin<name,
[UGenType1, PointerType<UGenType1, AS>, Int, Int,
UGenType1],
Attr.Convergent>;
}

foreach name = ["AtomicIAdd", "AtomicISub", "AtomicAnd", "AtomicOr",
"AtomicXor"] in {
def : SPVBuiltin<name,
[AIGenType1, PointerType<AIGenType1, AS>, Int, Int,
AIGenType1],
Attr.Convergent>;
}

def : SPVBuiltin<
"AtomicFlagTestAndSet", [Bool, PointerType<Int, AS>, Int, Int],
Attr.Convergent>;

def : SPVBuiltin<"AtomicFlagClear", [Void, PointerType<Int, AS>, Int, Int],
Attr.Convergent>;

foreach name = ["AtomicFMaxEXT", "AtomicFMinEXT", "AtomicFAddEXT"] in {
def : SPVBuiltin<name,
[FGenType1, PointerType<FGenType1, AS>, Int, Int,
FGenType1],
Attr.Convergent>;
}
}
237 changes: 237 additions & 0 deletions clang/test/CodeGenSPIRV/spirv-builtin-lookup-atomic.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
// RUN: %clang_cc1 -triple spir64 -fdeclare-spirv-builtins -emit-llvm %s -o - | FileCheck %s

#define AS_GLOBAL __attribute__((opencl_global))
#define AS_LOCAL __attribute__((opencl_local))
#define AS_PRIVATE __attribute__((opencl_private))
#define AS_GENERIC __attribute__((opencl_generic))

void test_flag(int AS_GLOBAL *a, int AS_LOCAL *b, int AS_PRIVATE *c,
int AS_GENERIC *d) {
__spirv_AtomicFlagTestAndSet(a, 1, 16);
__spirv_AtomicFlagTestAndSet(b, 2, 8);
__spirv_AtomicFlagTestAndSet(c, 4, 4);
__spirv_AtomicFlagTestAndSet(d, 2, 0);

__spirv_AtomicFlagClear(a, 1, 16);
__spirv_AtomicFlagClear(b, 2, 4);
__spirv_AtomicFlagClear(c, 4, 0);
__spirv_AtomicFlagClear(d, 2, 0);
}

template <class T>
void test_signed(T AS_GLOBAL *a, T AS_LOCAL *b, T AS_PRIVATE *c,
T AS_GENERIC *d) {
__spirv_AtomicLoad(a, 1, 16);
__spirv_AtomicLoad(b, 2, 8);
__spirv_AtomicLoad(c, 4, 4);
__spirv_AtomicLoad(d, 2, 0);

__spirv_AtomicStore(a, 1, 16, (T)0);
__spirv_AtomicStore(b, 2, 8, (T)0);
__spirv_AtomicStore(c, 4, 4, (T)0);
__spirv_AtomicStore(d, 2, 0, (T)0);

__spirv_AtomicExchange(a, 1, 16, (T)0);
__spirv_AtomicExchange(b, 2, 8, (T)0);
__spirv_AtomicExchange(c, 4, 4, (T)0);
__spirv_AtomicExchange(d, 2, 0, (T)0);

__spirv_AtomicCompareExchange(a, 1, 16, 0, (T)1, (T)0);
__spirv_AtomicCompareExchange(b, 2, 8, 0, (T)1, (T)0);
__spirv_AtomicCompareExchange(c, 4, 4, 0, (T)1, (T)0);
__spirv_AtomicCompareExchange(d, 2, 0, 0, (T)1, (T)0);

__spirv_AtomicCompareExchangeWeak(a, 1, 16, 0, (T)1, (T)0);
__spirv_AtomicCompareExchangeWeak(b, 2, 8, 0, (T)1, (T)0);
__spirv_AtomicCompareExchangeWeak(c, 4, 4, 0, (T)1, (T)0);
__spirv_AtomicCompareExchangeWeak(d, 2, 0, 0, (T)1, (T)0);

__spirv_AtomicIIncrement(a, 1, 16);
__spirv_AtomicIIncrement(b, 2, 8);
__spirv_AtomicIIncrement(c, 4, 4);
__spirv_AtomicIIncrement(d, 2, 0);

__spirv_AtomicIDecrement(a, 1, 16);
__spirv_AtomicIDecrement(b, 2, 8);
__spirv_AtomicIDecrement(c, 4, 4);
__spirv_AtomicIDecrement(d, 2, 0);

__spirv_AtomicSMin(a, 1, 16, (T)0);
__spirv_AtomicSMin(b, 2, 8, (T)0);
__spirv_AtomicSMin(c, 4, 4, (T)0);
__spirv_AtomicSMin(d, 2, 0, (T)0);

__spirv_AtomicSMax(a, 1, 16, (T)0);
__spirv_AtomicSMax(b, 2, 8, (T)0);
__spirv_AtomicSMax(c, 4, 4, (T)0);
__spirv_AtomicSMax(d, 2, 0, (T)0);

__spirv_AtomicIAdd(a, 1, 16, (T)0);
__spirv_AtomicIAdd(b, 2, 8, (T)0);
__spirv_AtomicIAdd(c, 4, 4, (T)0);
__spirv_AtomicIAdd(d, 2, 0, (T)0);

__spirv_AtomicISub(a, 1, 16, (T)0);
__spirv_AtomicISub(b, 2, 8, (T)0);
__spirv_AtomicISub(c, 4, 4, (T)0);
__spirv_AtomicISub(d, 2, 0, (T)0);

__spirv_AtomicAnd(a, 1, 16, (T)0);
__spirv_AtomicAnd(b, 2, 8, (T)0);
__spirv_AtomicAnd(c, 4, 4, (T)0);
__spirv_AtomicAnd(d, 2, 0, (T)0);

__spirv_AtomicOr(a, 1, 16, (T)0);
__spirv_AtomicOr(b, 2, 8, (T)0);
__spirv_AtomicOr(c, 4, 4, (T)0);
__spirv_AtomicOr(d, 2, 0, (T)0);

__spirv_AtomicXor(a, 1, 16, (T)0);
__spirv_AtomicXor(b, 2, 8, (T)0);
__spirv_AtomicXor(c, 4, 4, (T)0);
__spirv_AtomicXor(d, 2, 0, (T)0);
}

template <class T>
void test_unsigned(T AS_GLOBAL *a, T AS_LOCAL *b, T AS_PRIVATE *c,
T AS_GENERIC *d) {

__spirv_AtomicUMin(a, 1, 16, (T)0);
__spirv_AtomicUMin(b, 2, 8, (T)0);
__spirv_AtomicUMin(c, 4, 4, (T)0);
__spirv_AtomicUMin(d, 2, 0, (T)0);

__spirv_AtomicUMax(a, 1, 16, (T)0);
__spirv_AtomicUMax(b, 2, 8, (T)0);
__spirv_AtomicUMax(c, 4, 4, (T)0);
__spirv_AtomicUMax(d, 2, 0, (T)0);
}

template <class T>
void test_float(T AS_GLOBAL *a, T AS_LOCAL *b, T AS_PRIVATE *c,
T AS_GENERIC *d) {
__spirv_AtomicFMaxEXT(a, 1, 16, (T)0);
__spirv_AtomicFMaxEXT(b, 2, 8, (T)0);
__spirv_AtomicFMaxEXT(c, 4, 4, (T)0);
__spirv_AtomicFMaxEXT(d, 2, 0, (T)0);

__spirv_AtomicFMinEXT(a, 1, 16, (T)0);
__spirv_AtomicFMinEXT(b, 2, 8, (T)0);
__spirv_AtomicFMinEXT(c, 4, 4, (T)0);
__spirv_AtomicFMinEXT(d, 2, 0, (T)0);

__spirv_AtomicFAddEXT(a, 1, 16, (T)0);
__spirv_AtomicFAddEXT(b, 2, 8, (T)0);
__spirv_AtomicFAddEXT(c, 4, 4, (T)0);
__spirv_AtomicFAddEXT(d, 2, 0, (T)0);
}

void foo() {
int AS_GLOBAL *a;
int AS_LOCAL *b;
int AS_PRIVATE *c;
int AS_GENERIC *d;
test_flag(a, b, c, d);

test_signed<int>(a, b, c, d);

unsigned int AS_GLOBAL *ua;
unsigned int AS_LOCAL *ub;
unsigned int AS_PRIVATE *uc;
unsigned int AS_GENERIC *ud;
test_unsigned<unsigned int>(ua, ub, uc, ud);

float AS_GLOBAL *fa;
float AS_LOCAL *fb;
float AS_PRIVATE *fc;
float AS_GENERIC *fd;
test_float<float>(fa, fb, fc, fd);
}

// CHECK: call spir_func noundef zeroext i1 @_Z28__spirv_AtomicFlagTestAndSetPU3AS1iii(
// CHECK: call spir_func noundef zeroext i1 @_Z28__spirv_AtomicFlagTestAndSetPU3AS3iii(
// CHECK: call spir_func noundef zeroext i1 @_Z28__spirv_AtomicFlagTestAndSetPiii(
// CHECK: call spir_func noundef zeroext i1 @_Z28__spirv_AtomicFlagTestAndSetPU3AS4iii(
// CHECK: call spir_func void @_Z23__spirv_AtomicFlagClearPU3AS1iii(
// CHECK: call spir_func void @_Z23__spirv_AtomicFlagClearPU3AS3iii(
// CHECK: call spir_func void @_Z23__spirv_AtomicFlagClearPiii(
// CHECK: call spir_func void @_Z23__spirv_AtomicFlagClearPU3AS4iii(

// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicLoadPU3AS1iii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicLoadPU3AS3iii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicLoadPiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicLoadPU3AS4iii(
// CHECK: call spir_func void @_Z19__spirv_AtomicStorePU3AS1iiii(
// CHECK: call spir_func void @_Z19__spirv_AtomicStorePU3AS3iiii(
// CHECK: call spir_func void @_Z19__spirv_AtomicStorePiiii(
// CHECK: call spir_func void @_Z19__spirv_AtomicStorePU3AS4iiii(
// CHECK: call spir_func noundef i32 @_Z22__spirv_AtomicExchangePU3AS1iiii(
// CHECK: call spir_func noundef i32 @_Z22__spirv_AtomicExchangePU3AS3iiii(
// CHECK: call spir_func noundef i32 @_Z22__spirv_AtomicExchangePiiii(
// CHECK: call spir_func noundef i32 @_Z22__spirv_AtomicExchangePU3AS4iiii(
// CHECK: call spir_func noundef i32 @_Z29__spirv_AtomicCompareExchangePU3AS1iiiiii(
// CHECK: call spir_func noundef i32 @_Z29__spirv_AtomicCompareExchangePU3AS3iiiiii(
// CHECK: call spir_func noundef i32 @_Z29__spirv_AtomicCompareExchangePiiiiii(
// CHECK: call spir_func noundef i32 @_Z29__spirv_AtomicCompareExchangePU3AS4iiiiii(
// CHECK: call spir_func noundef i32 @_Z33__spirv_AtomicCompareExchangeWeakPU3AS1iiiiii(
// CHECK: call spir_func noundef i32 @_Z33__spirv_AtomicCompareExchangeWeakPU3AS3iiiiii(
// CHECK: call spir_func noundef i32 @_Z33__spirv_AtomicCompareExchangeWeakPiiiiii(
// CHECK: call spir_func noundef i32 @_Z33__spirv_AtomicCompareExchangeWeakPU3AS4iiiiii(
// CHECK: call spir_func noundef i32 @_Z24__spirv_AtomicIIncrementPU3AS1iii(
// CHECK: call spir_func noundef i32 @_Z24__spirv_AtomicIIncrementPU3AS3iii(
// CHECK: call spir_func noundef i32 @_Z24__spirv_AtomicIIncrementPiii(
// CHECK: call spir_func noundef i32 @_Z24__spirv_AtomicIIncrementPU3AS4iii(
// CHECK: call spir_func noundef i32 @_Z24__spirv_AtomicIDecrementPU3AS1iii(
// CHECK: call spir_func noundef i32 @_Z24__spirv_AtomicIDecrementPU3AS3iii(
// CHECK: call spir_func noundef i32 @_Z24__spirv_AtomicIDecrementPiii(
// CHECK: call spir_func noundef i32 @_Z24__spirv_AtomicIDecrementPU3AS4iii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicSMinPU3AS1iiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicSMinPU3AS3iiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicSMinPiiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicSMinPU3AS4iiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicSMaxPU3AS1iiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicSMaxPU3AS3iiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicSMaxPiiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicSMaxPU3AS4iiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicIAddPU3AS1iiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicIAddPU3AS3iiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicIAddPiiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicIAddPU3AS4iiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicISubPU3AS1iiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicISubPU3AS3iiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicISubPiiii(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicISubPU3AS4iiii(
// CHECK: call spir_func noundef i32 @_Z17__spirv_AtomicAndPU3AS1iiii(
// CHECK: call spir_func noundef i32 @_Z17__spirv_AtomicAndPU3AS3iiii(
// CHECK: call spir_func noundef i32 @_Z17__spirv_AtomicAndPiiii(
// CHECK: call spir_func noundef i32 @_Z17__spirv_AtomicAndPU3AS4iiii(
// CHECK: call spir_func noundef i32 @_Z16__spirv_AtomicOrPU3AS1iiii(
// CHECK: call spir_func noundef i32 @_Z16__spirv_AtomicOrPU3AS3iiii(
// CHECK: call spir_func noundef i32 @_Z16__spirv_AtomicOrPiiii(
// CHECK: call spir_func noundef i32 @_Z16__spirv_AtomicOrPU3AS4iiii(
// CHECK: call spir_func noundef i32 @_Z17__spirv_AtomicXorPU3AS1iiii(
// CHECK: call spir_func noundef i32 @_Z17__spirv_AtomicXorPU3AS3iiii(
// CHECK: call spir_func noundef i32 @_Z17__spirv_AtomicXorPiiii(
// CHECK: call spir_func noundef i32 @_Z17__spirv_AtomicXorPU3AS4iiii(

// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicUMinPU3AS1jiij(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicUMinPU3AS3jiij(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicUMinPjiij(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicUMinPU3AS4jiij(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicUMaxPU3AS1jiij(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicUMaxPU3AS3jiij(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicUMaxPjiij(
// CHECK: call spir_func noundef i32 @_Z18__spirv_AtomicUMaxPU3AS4jiij(

// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFMaxEXTPU3AS1fiif(
// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFMaxEXTPU3AS3fiif(
// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFMaxEXTPfiif(
// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFMaxEXTPU3AS4fiif(
// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFMinEXTPU3AS1fiif(
// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFMinEXTPU3AS3fiif(
// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFMinEXTPfiif(
// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFMinEXTPU3AS4fiif(
// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFAddEXTPU3AS1fiif(
// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFAddEXTPU3AS3fiif(
// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFAddEXTPfiif(
// CHECK: call spir_func noundef float @_Z21__spirv_AtomicFAddEXTPU3AS4fiif(
17 changes: 7 additions & 10 deletions libclc/generic/lib/atomic/atomic_add.cl
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
#include <clc/clc.h>
#include <libspirv/spirv.h>

#define IMPL(TYPE, TYPE_MANGLED, AS, AS_MANGLED) \
_CLC_OVERLOAD _CLC_DEF TYPE atomic_add(volatile AS TYPE *p, TYPE val) { \
/* TODO: Stop manually mangling this name. Need C++ namespaces to get the \
* exact mangling. */ \
return _Z18__spirv_AtomicIAddPU3##AS_MANGLED##TYPE_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagE##TYPE_MANGLED( \
p, Device, SequentiallyConsistent, val); \
#define IMPL(TYPE, AS) \
_CLC_OVERLOAD _CLC_DEF TYPE atomic_add(volatile AS TYPE *p, TYPE val) { \
return __spirv_AtomicIAdd((AS TYPE *)p, Device, SequentiallyConsistent, val); \
}

IMPL(int, i, global, AS1)
IMPL(unsigned int, j, global, AS1)
IMPL(int, i, local, AS3)
IMPL(unsigned int, j, local, AS3)
IMPL(int, global)
IMPL(unsigned int, global)
IMPL(int, local)
IMPL(unsigned int, local)
#undef IMPL
17 changes: 7 additions & 10 deletions libclc/generic/lib/atomic/atomic_and.cl
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
#include <clc/clc.h>
#include <libspirv/spirv.h>

#define IMPL(TYPE, TYPE_MANGLED, AS, AS_MANGLED) \
_CLC_OVERLOAD _CLC_DEF TYPE atomic_and(volatile AS TYPE *p, TYPE val) { \
/* TODO: Stop manually mangling this name. Need C++ namespaces to get the \
* exact mangling. */ \
return _Z17__spirv_AtomicAndPU3##AS_MANGLED##TYPE_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagE##TYPE_MANGLED( \
p, Device, SequentiallyConsistent, val); \
#define IMPL(TYPE, AS) \
_CLC_OVERLOAD _CLC_DEF TYPE atomic_and(volatile AS TYPE *p, TYPE val) { \
return __spirv_AtomicAnd((AS TYPE *)p, Device, SequentiallyConsistent, val); \
}

IMPL(int, i, global, AS1)
IMPL(unsigned int, j, global, AS1)
IMPL(int, i, local, AS3)
IMPL(unsigned int, j, local, AS3)
IMPL(int, global)
IMPL(unsigned int, global)
IMPL(int, local)
IMPL(unsigned int, local)
#undef IMPL
20 changes: 9 additions & 11 deletions libclc/generic/lib/atomic/atomic_cmpxchg.cl
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
#include <clc/clc.h>
#include <libspirv/spirv.h>

#define IMPL(TYPE, TYPE_MANGLED, AS, AS_MANGLED) \
_CLC_OVERLOAD _CLC_DEF TYPE atomic_cmpxchg(volatile AS TYPE *p, TYPE cmp, \
TYPE val) { \
/* TODO: Stop manually mangling this name. Need C++ namespaces to get the \
* exact mangling. */ \
return _Z29__spirv_AtomicCompareExchangePU3##AS_MANGLED##TYPE_MANGLED##N5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagES5_##TYPE_MANGLED##TYPE_MANGLED( \
p, Device, SequentiallyConsistent, SequentiallyConsistent, val, cmp); \
#define IMPL(TYPE, AS) \
_CLC_OVERLOAD _CLC_DEF TYPE atomic_cmpxchg(volatile AS TYPE *p, TYPE cmp, \
TYPE val) { \
return __spirv_AtomicCompareExchange((AS TYPE *)p, Device, \
SequentiallyConsistent, SequentiallyConsistent, val, cmp); \
}

IMPL(int, i, global, AS1)
IMPL(unsigned int, j, global, AS1)
IMPL(int, i, local, AS3)
IMPL(unsigned int, j, local, AS3)
IMPL(int, global)
IMPL(unsigned int, global)
IMPL(int, local)
IMPL(unsigned int, local)
#undef IMPL
Loading
Loading