From 747d440ef41d71c0df06e1572d79e7fdf9a3e1a8 Mon Sep 17 00:00:00 2001 From: Victor Lomuller Date: Thu, 5 Jun 2025 22:56:35 +0100 Subject: [PATCH] [SPIRV] Fix handling of __builtin_spirv_generic_cast_to_ptr_explicit for SYCL __builtin_spirv_generic_cast_to_ptr_explicit was added upstreaming but because it has limited SYCL support, tests can't run properly. --- clang/lib/Headers/__clang_spirv_builtins.h | 27 ++++++++++--------- clang/lib/Sema/SemaDeclAttr.cpp | 3 ++- .../Builtins/generic_cast_to_ptr_explicit.c | 12 ++++++--- clang/test/Headers/spirv_functions.cpp | 7 ++++- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/clang/lib/Headers/__clang_spirv_builtins.h b/clang/lib/Headers/__clang_spirv_builtins.h index e344ed52571a7..ea060dc5bfc33 100644 --- a/clang/lib/Headers/__clang_spirv_builtins.h +++ b/clang/lib/Headers/__clang_spirv_builtins.h @@ -26,8 +26,10 @@ #define __constant __attribute__((opencl_constant)) #ifdef __SYCL_DEVICE_ONLY__ #define __generic +#define __SPIRV_SYCL_EXTERNAL __attribute__((sycl_device)) #else #define __generic __attribute__((opencl_generic)) +#define __SPIRV_SYCL_EXTERNAL #endif // Check if SPIR-V builtins are supported. @@ -45,60 +47,60 @@ // OpGenericCastToPtrExplicit -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __global void *__spirv_GenericCastToPtrExplicit_ToGlobal(__generic void *, int) __SPIRV_NOEXCEPT; -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __global const void * __spirv_GenericCastToPtrExplicit_ToGlobal(__generic const void *, int) __SPIRV_NOEXCEPT; -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __global volatile void * __spirv_GenericCastToPtrExplicit_ToGlobal(__generic volatile void *, int) __SPIRV_NOEXCEPT; -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __global const volatile void * __spirv_GenericCastToPtrExplicit_ToGlobal(__generic const volatile void *, int) __SPIRV_NOEXCEPT; -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __local void *__spirv_GenericCastToPtrExplicit_ToLocal(__generic void *, int) __SPIRV_NOEXCEPT; -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __local const void * __spirv_GenericCastToPtrExplicit_ToLocal(__generic const void *, int) __SPIRV_NOEXCEPT; -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __local volatile void * __spirv_GenericCastToPtrExplicit_ToLocal(__generic volatile void *, int) __SPIRV_NOEXCEPT; -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __local const volatile void * __spirv_GenericCastToPtrExplicit_ToLocal(__generic const volatile void *, int) __SPIRV_NOEXCEPT; -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __private void * __spirv_GenericCastToPtrExplicit_ToPrivate(__generic void *, int) __SPIRV_NOEXCEPT; -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __private const void * __spirv_GenericCastToPtrExplicit_ToPrivate(__generic const void *, int) __SPIRV_NOEXCEPT; -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __private volatile void * __spirv_GenericCastToPtrExplicit_ToPrivate(__generic volatile void *, int) __SPIRV_NOEXCEPT; -extern __SPIRV_overloadable +extern __SPIRV_overloadable __SPIRV_SYCL_EXTERNAL __SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit) __private const volatile void * __spirv_GenericCastToPtrExplicit_ToPrivate(__generic const volatile void *, @@ -172,6 +174,7 @@ __spirv_GenericCastToPtr_ToPrivate(__generic const volatile void *p, #undef __local #undef __constant #undef __generic +#undef __SPIRV_SYCL_EXTERNAL #undef __SPIRV_BUILTIN_ALIAS #undef __SPIRV_NOEXCEPT diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 8b2aa5b5e6115..357bb8035bea9 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5937,11 +5937,12 @@ static void handleBuiltinAliasAttr(Sema &S, Decl *D, bool IsSPIRV = S.Context.getTargetInfo().getTriple().isSPIRV(); bool IsHLSL = S.Context.getLangOpts().HLSL; bool IsSYCL = S.Context.getLangOpts().isSYCL(); + bool IsTSBuiltin = S.Context.BuiltinInfo.isTSBuiltin(BuiltinID); if ((IsAArch64 && !S.ARM().SveAliasValid(BuiltinID, AliasName)) || (IsARM && !S.ARM().MveAliasValid(BuiltinID, AliasName) && !S.ARM().CdeAliasValid(BuiltinID, AliasName)) || (IsRISCV && !S.RISCV().isAliasValid(BuiltinID, AliasName)) || - (IsSYCL && !SYCLAliasValid(S.Context, BuiltinID)) || + (IsSYCL && !IsTSBuiltin && !SYCLAliasValid(S.Context, BuiltinID)) || (!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL && !IsSYCL && !IsSPIRV)) { S.Diag(AL.getLoc(), diag::err_attribute_builtin_alias) << AL; return; diff --git a/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c b/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c index 8cfe650f4db10..0197fba1f7fa1 100644 --- a/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c +++ b/clang/test/CodeGenSPIRV/Builtins/generic_cast_to_ptr_explicit.c @@ -2,13 +2,19 @@ // RUN: %clang_cc1 -O1 -triple spirv64 -cl-std=CL3.0 -x cl %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -O1 -triple spirv32 -cl-std=CL3.0 -x cl %s -emit-llvm -o - | FileCheck %s +#ifdef __SYCL_DEVICE_ONLY__ +#define SYCL_EXTERNAL __attribute__((sycl_device)) +#else +#define SYCL_EXTERNAL +#endif + // CHECK: spir_func noundef ptr @test_cast_to_private( // CHECK-SAME: ptr addrspace(4) noundef readnone [[P:%.*]] // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr @llvm.spv.generic.cast.to.ptr.explicit.p0(ptr addrspace(4) %p) // CHECK-NEXT: ret ptr [[SPV_CAST]] // -__attribute__((opencl_private)) int* test_cast_to_private(int* p) { +SYCL_EXTERNAL __attribute__((opencl_private)) int* test_cast_to_private(int* p) { return __builtin_spirv_generic_cast_to_ptr_explicit(p, 7); } @@ -18,7 +24,7 @@ __attribute__((opencl_private)) int* test_cast_to_private(int* p) { // CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr addrspace(1) @llvm.spv.generic.cast.to.ptr.explicit.p1(ptr addrspace(4) %p) // CHECK-NEXT: ret ptr addrspace(1) [[SPV_CAST]] // -__attribute__((opencl_global)) int* test_cast_to_global(int* p) { +SYCL_EXTERNAL __attribute__((opencl_global)) int* test_cast_to_global(int* p) { return __builtin_spirv_generic_cast_to_ptr_explicit(p, 5); } @@ -28,6 +34,6 @@ __attribute__((opencl_global)) int* test_cast_to_global(int* p) { // CHECK-NEXT: [[SPV_CAST:%.*]] = tail call noundef ptr addrspace(3) @llvm.spv.generic.cast.to.ptr.explicit.p3(ptr addrspace(4) %p) // CHECK-NEXT: ret ptr addrspace(3) [[SPV_CAST]] // -__attribute__((opencl_local)) int* test_cast_to_local(int* p) { +SYCL_EXTERNAL __attribute__((opencl_local)) int* test_cast_to_local(int* p) { return __builtin_spirv_generic_cast_to_ptr_explicit(p, 4); } diff --git a/clang/test/Headers/spirv_functions.cpp b/clang/test/Headers/spirv_functions.cpp index ff036b75faf02..b00c84ce942a9 100644 --- a/clang/test/Headers/spirv_functions.cpp +++ b/clang/test/Headers/spirv_functions.cpp @@ -1,6 +1,11 @@ // RUN: %clang_cc1 -Wno-unused-value -O0 -internal-isystem %S/../../lib/Headers -include __clang_spirv_builtins.h -triple spirv64 -emit-llvm %s -fsycl-is-device -o - | FileCheck %s -check-prefixes=SPV // RUN: %clang_cc1 -Wno-unused-value -O0 -internal-isystem %S/../../lib/Headers -include __clang_spirv_builtins.h -triple nvptx64 -emit-llvm %s -fsycl-is-device -o - | FileCheck %s -check-prefixes=NV +#ifdef __SYCL_DEVICE_ONLY__ +#define SYCL_EXTERNAL __attribute__((sycl_device)) +#else +#define SYCL_EXTERNAL +#endif // SPV: void @_Z9test_castPi // SPV: call noundef ptr addrspace(1) @llvm.spv.generic.cast.to.ptr.explicit.p1 @@ -15,7 +20,7 @@ // NV: call noundef ptr @_Z42__spirv_GenericCastToPtrExplicit_ToPrivatePvi // NV: addrspacecast ptr %{{.*}} to ptr addrspace(1) // NV: addrspacecast ptr %{{.*}} to ptr addrspace(3) -void test_cast(int* p) { +SYCL_EXTERNAL void test_cast(int* p) { __spirv_GenericCastToPtrExplicit_ToGlobal(p, 5); __spirv_GenericCastToPtrExplicit_ToLocal(p, 4); __spirv_GenericCastToPtrExplicit_ToPrivate(p, 7);