[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -25,20 +40,29 @@ int main() { auto lambda2 = [](int){}; auto lambda3 = [](double){}; - kernel(lambda1); - kernel2(lambda2); - kernel3(lambda3); + kernel_wrapper(lambda1); + kernel2_wrapper(lambda2); + kernel3_wrapper(lambda3); // Ensure the kernels are named the same between the device and host // invocations. + kernel_wrapper([](){ (void)__builtin_sycl_unique_stable_name(decltype(lambda1)); (void)__builtin_sycl_unique_stable_name(decltype(lambda2)); (void)__builtin_sycl_unique_stable_name(decltype(lambda3)); + }); // Make sure the following 3 are the same between the host and device compile. // Note that these are NOT the same value as each other, they differ by the // signature. // CHECK: private unnamed_addr [[$ADDRSPACE]]constant [17 x i8] c"_ZTSZ4mainEUlvE_\00" // CHECK: private unnamed_addr [[$ADDRSPACE]]constant [17 x i8] c"_ZTSZ4mainEUliE_\00" // CHECK: private unnamed_addr [[$ADDRSPACE]]constant [17 x i8] c"_ZTSZ4mainEUldE_\00" + + // On Windows, ensure that we haven't broken the 'lambda numbering' for thex schittir wrote: Thank you for the review, @Fznamznon! https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -verify %s + +// expected-warning@+1{{'sycl_external' attribute only applies to functions}} +[[clang::sycl_external]] int a; + + +// expected-warning@+2{{'sycl_external' attribute only applies to functions}} +struct s { +[[clang::sycl_external]] int b; +}; + +// FIXME: The first declaration of a function is required to have the attribute. schittir wrote: SYCL spec 2020 section 5.10.0 describes it so: https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#subsec:syclexternal https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -29,21 +29,10 @@ int foo() { } template -__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) { +[[clang::sycl_external]] void kernel_single_task(const Func &kernelFunc) { schittir wrote: Agreed. It should have been [[clang::sycl_kernel_entry_point(Name)]] https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -1,128 +1,128 @@ // RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s void bar(int &Data) {} -// CHECK: define dso_local void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) % +// CHECK-DAG: define {{.*}} void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) % schittir wrote: I see this in place: https://github.com/intel/llvm/commit/1ea43e2a77667eab3d8702732afe62cf9f6347a9, and followed the pattern established here to help avoid downstream conflicts. Actually checking the calling convention and linkage makes sense too. https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
https://github.com/schittir updated https://github.com/llvm/llvm-project/pull/140282 >From abdbf8905d324f9b935b34bbc97c508ede5ac028 Mon Sep 17 00:00:00 2001 From: "Chittireddy, Sindhu" Date: Fri, 16 May 2025 08:51:06 -0700 Subject: [PATCH 01/11] Add sycl_external attribute --- clang/include/clang/Basic/Attr.td | 20 ++- clang/include/clang/Basic/AttrDocs.td | 11 .../clang/Basic/DiagnosticSemaKinds.td| 5 ++ clang/include/clang/Sema/SemaSYCL.h | 1 + clang/lib/AST/ASTContext.cpp | 7 +++ clang/lib/Sema/SemaDeclAttr.cpp | 3 ++ clang/lib/Sema/SemaSYCL.cpp | 11 .../test/SemaSYCL/sycl-external-attribute.cpp | 52 +++ 8 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaSYCL/sycl-external-attribute.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index ccd13a4cca4dd..1c13d0eb23f3b 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -143,6 +143,7 @@ def SharedVar : SubsetSubjecthasGlobalStorage()}], "global variables">; + def ExternalGlobalVar : SubsetSubjecthasGlobalStorage() && S->getStorageClass()!=StorageClass::SC_Static && @@ -408,10 +409,14 @@ class SubjectList subjects, SubjectDiag diag = WarnDiag, string CustomDiag = customDiag; } -class LangOpt { +class LangOpt { // The language option to test; ignored when custom code is supplied. string Name = name; + // If set to 1, the attribute is accepted but is silently ignored. This is + // useful in multi-compilation situations like SYCL. + bit SilentlyIgnore = silentlyIgnore; + // A custom predicate, written as an expression evaluated in a context with // "LangOpts" bound. code CustomCode = customCode; @@ -422,6 +427,7 @@ def CUDA : LangOpt<"CUDA">; def HIP : LangOpt<"HIP">; def SYCLHost : LangOpt<"SYCLIsHost">; def SYCLDevice : LangOpt<"SYCLIsDevice">; +def SilentlyIgnoreSYCLHost : LangOpt<"SYCLIsHost", "", 1>; def COnly : LangOpt<"", "!LangOpts.CPlusPlus">; def CPlusPlus : LangOpt<"CPlusPlus">; def OpenCL : LangOpt<"OpenCL">; @@ -1545,6 +1551,18 @@ def SYCLKernel : InheritableAttr { let Documentation = [SYCLKernelDocs]; } +def GlobalStorageNonLocalVar : SubsetSubjecthasGlobalStorage() && + !S->isLocalVarDeclOrParm()}], + "global variables">; + +def SYCLExternal : InheritableAttr { + let Spellings = [GNU<"sycl_external">]; + let Subjects = SubjectList<[Function, GlobalStorageNonLocalVar]>; + let LangOpts = [SYCLDevice, SilentlyIgnoreSYCLHost]; + let Documentation = [SYCLExternalDocs]; +} + def SYCLKernelEntryPoint : InheritableAttr { let Spellings = [Clang<"sycl_kernel_entry_point">]; let Args = [ diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 5fb5f16680b41..2eef46a1348f3 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -472,6 +472,17 @@ The SYCL kernel in the previous code sample meets these expectations. }]; } +def SYCLExternalDocs : Documentation { + let Category = DocCatFunction; + let Heading = "sycl_external"; + let Content = [{ +The ``sycl_external`` attribute (or the ``SYCL_EXTERNAL`` macro) can only be applied to +functions, and indicates that the function must be treated as a device function and +must be emitted even if it has no direct uses from other device functions. +All ``sycl_external`` function callees implicitly inherit this attribute. + }]; +} + def SYCLKernelEntryPointDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 3efe9593b8633..9228d388bc10b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12746,6 +12746,11 @@ def err_sycl_special_type_num_init_method : Error< "types with 'sycl_special_class' attribute must have one and only one '__init' " "method defined">; +//SYCL external attribute diagnostics +def err_sycl_attribute_internal_decl +: Error<"%0 attribute cannot be applied to a %select{function|variable}1" +" without external linkage">; + // SYCL kernel entry point diagnostics def err_sycl_entry_point_invalid : Error< "'sycl_kernel_entry_point' attribute cannot be applied to a" diff --git a/clang/include/clang/Sema/SemaSYCL.h b/clang/include/clang/Sema/SemaSYCL.h index b47b2f155ef93..099cc56b0ef92 100644 --- a/clang/include/clang/Sema/SemaSYCL.h +++ b/clang/include/clang/Sema/SemaSYCL.h @@ -62,6 +62,7 @@ class SemaSYCL : public SemaBase { ParsedType ParsedTy); void handleKernelAttr(Decl *D, const ParsedAttr &AL); + void handle
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
https://github.com/schittir updated https://github.com/llvm/llvm-project/pull/140282 >From abdbf8905d324f9b935b34bbc97c508ede5ac028 Mon Sep 17 00:00:00 2001 From: "Chittireddy, Sindhu" Date: Fri, 16 May 2025 08:51:06 -0700 Subject: [PATCH 01/10] Add sycl_external attribute --- clang/include/clang/Basic/Attr.td | 20 ++- clang/include/clang/Basic/AttrDocs.td | 11 .../clang/Basic/DiagnosticSemaKinds.td| 5 ++ clang/include/clang/Sema/SemaSYCL.h | 1 + clang/lib/AST/ASTContext.cpp | 7 +++ clang/lib/Sema/SemaDeclAttr.cpp | 3 ++ clang/lib/Sema/SemaSYCL.cpp | 11 .../test/SemaSYCL/sycl-external-attribute.cpp | 52 +++ 8 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaSYCL/sycl-external-attribute.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index ccd13a4cca4dd..1c13d0eb23f3b 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -143,6 +143,7 @@ def SharedVar : SubsetSubjecthasGlobalStorage()}], "global variables">; + def ExternalGlobalVar : SubsetSubjecthasGlobalStorage() && S->getStorageClass()!=StorageClass::SC_Static && @@ -408,10 +409,14 @@ class SubjectList subjects, SubjectDiag diag = WarnDiag, string CustomDiag = customDiag; } -class LangOpt { +class LangOpt { // The language option to test; ignored when custom code is supplied. string Name = name; + // If set to 1, the attribute is accepted but is silently ignored. This is + // useful in multi-compilation situations like SYCL. + bit SilentlyIgnore = silentlyIgnore; + // A custom predicate, written as an expression evaluated in a context with // "LangOpts" bound. code CustomCode = customCode; @@ -422,6 +427,7 @@ def CUDA : LangOpt<"CUDA">; def HIP : LangOpt<"HIP">; def SYCLHost : LangOpt<"SYCLIsHost">; def SYCLDevice : LangOpt<"SYCLIsDevice">; +def SilentlyIgnoreSYCLHost : LangOpt<"SYCLIsHost", "", 1>; def COnly : LangOpt<"", "!LangOpts.CPlusPlus">; def CPlusPlus : LangOpt<"CPlusPlus">; def OpenCL : LangOpt<"OpenCL">; @@ -1545,6 +1551,18 @@ def SYCLKernel : InheritableAttr { let Documentation = [SYCLKernelDocs]; } +def GlobalStorageNonLocalVar : SubsetSubjecthasGlobalStorage() && + !S->isLocalVarDeclOrParm()}], + "global variables">; + +def SYCLExternal : InheritableAttr { + let Spellings = [GNU<"sycl_external">]; + let Subjects = SubjectList<[Function, GlobalStorageNonLocalVar]>; + let LangOpts = [SYCLDevice, SilentlyIgnoreSYCLHost]; + let Documentation = [SYCLExternalDocs]; +} + def SYCLKernelEntryPoint : InheritableAttr { let Spellings = [Clang<"sycl_kernel_entry_point">]; let Args = [ diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 5fb5f16680b41..2eef46a1348f3 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -472,6 +472,17 @@ The SYCL kernel in the previous code sample meets these expectations. }]; } +def SYCLExternalDocs : Documentation { + let Category = DocCatFunction; + let Heading = "sycl_external"; + let Content = [{ +The ``sycl_external`` attribute (or the ``SYCL_EXTERNAL`` macro) can only be applied to +functions, and indicates that the function must be treated as a device function and +must be emitted even if it has no direct uses from other device functions. +All ``sycl_external`` function callees implicitly inherit this attribute. + }]; +} + def SYCLKernelEntryPointDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 3efe9593b8633..9228d388bc10b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12746,6 +12746,11 @@ def err_sycl_special_type_num_init_method : Error< "types with 'sycl_special_class' attribute must have one and only one '__init' " "method defined">; +//SYCL external attribute diagnostics +def err_sycl_attribute_internal_decl +: Error<"%0 attribute cannot be applied to a %select{function|variable}1" +" without external linkage">; + // SYCL kernel entry point diagnostics def err_sycl_entry_point_invalid : Error< "'sycl_kernel_entry_point' attribute cannot be applied to a" diff --git a/clang/include/clang/Sema/SemaSYCL.h b/clang/include/clang/Sema/SemaSYCL.h index b47b2f155ef93..099cc56b0ef92 100644 --- a/clang/include/clang/Sema/SemaSYCL.h +++ b/clang/include/clang/Sema/SemaSYCL.h @@ -62,6 +62,7 @@ class SemaSYCL : public SemaBase { ParsedType ParsedTy); void handleKernelAttr(Decl *D, const ParsedAttr &AL); + void handle
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -7179,6 +7179,12 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_EnumExtensibility: handleEnumExtensibilityAttr(S, D, AL); break; + case ParsedAttr::AT_SYCLKernel: +S.SYCL().handleKernelAttr(D, AL); +break; Fznamznon wrote: I think this is causing the build failures in the CI now. ```suggestion ``` https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -1,128 +1,128 @@ // RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s void bar(int &Data) {} -// CHECK: define dso_local void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) % +// CHECK-DAG: define {{.*}} void @[[RAW_REF:[a-zA-Z0-9_]+]](ptr noundef nonnull align 4 dereferenceable(4) % Fznamznon wrote: We could actually check the calling convention and linkage instead of simply skipping it. https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -verify %s + +// Semantic tests for sycl_external attribute + +[[clang::sycl_external(3)]] // expected-error {{'sycl_external' attribute takes no arguments}} +void bar() {} + +[[clang::sycl_external]] // expected-error {{'sycl_external' can only be applied to functions with external linkage}} Fznamznon wrote: The AttrDocs.td should probably mention that the attribute only applies to external functions. https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -verify %s + +// expected-warning@+1{{'sycl_external' attribute only applies to functions}} +[[clang::sycl_external]] int a; + + +// expected-warning@+2{{'sycl_external' attribute only applies to functions}} +struct s { +[[clang::sycl_external]] int b; +}; + +// FIXME: The first declaration of a function is required to have the attribute. Fznamznon wrote: Why? https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -29,21 +29,10 @@ int foo() { } template -__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) { +[[clang::sycl_external]] void kernel_single_task(const Func &kernelFunc) { Fznamznon wrote: I think it was meant to be a kernel, so sycl_kernel_entry_point attribute would be appropriate here. ```suggestion [[clang::sycl_kernel_entry_point]] void kernel_single_task(const Func &kernelFunc) { ``` https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -25,20 +40,29 @@ int main() { auto lambda2 = [](int){}; auto lambda3 = [](double){}; - kernel(lambda1); - kernel2(lambda2); - kernel3(lambda3); + kernel_wrapper(lambda1); + kernel2_wrapper(lambda2); + kernel3_wrapper(lambda3); // Ensure the kernels are named the same between the device and host // invocations. + kernel_wrapper([](){ (void)__builtin_sycl_unique_stable_name(decltype(lambda1)); (void)__builtin_sycl_unique_stable_name(decltype(lambda2)); (void)__builtin_sycl_unique_stable_name(decltype(lambda3)); + }); // Make sure the following 3 are the same between the host and device compile. // Note that these are NOT the same value as each other, they differ by the // signature. // CHECK: private unnamed_addr [[$ADDRSPACE]]constant [17 x i8] c"_ZTSZ4mainEUlvE_\00" // CHECK: private unnamed_addr [[$ADDRSPACE]]constant [17 x i8] c"_ZTSZ4mainEUliE_\00" // CHECK: private unnamed_addr [[$ADDRSPACE]]constant [17 x i8] c"_ZTSZ4mainEUldE_\00" + + // On Windows, ensure that we haven't broken the 'lambda numbering' for thex Fznamznon wrote: ```suggestion // On Windows, ensure that we haven't broken the 'lambda numbering' for the ``` https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -476,6 +476,33 @@ The SYCL kernel in the previous code sample meets these expectations. }]; } +def SYCLExternalDocs : Documentation { + let Category = DocCatFunction; + let Heading = "sycl_external"; + let Content = [{ +The ``sycl_external`` attribute (or the ``SYCL_EXTERNAL`` macro) can only be applied to Fznamznon wrote: I am not sure it is a good idea to mention the macro unless we introduce it with this PR too. https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL Upstreaming] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -476,6 +476,33 @@ The SYCL kernel in the previous code sample meets these expectations. }]; } +def SYCLExternalDocs : Documentation { + let Category = DocCatFunction; + let Heading = "sycl_external"; + let Content = [{ +The ``sycl_external`` attribute (or the ``SYCL_EXTERNAL`` macro) can only be applied to +functions, and indicates that the function must be treated as a device function and +must be emitted even if it has no direct uses from other device functions. +All ``sycl_external`` function callees implicitly inherit this attribute. Fznamznon wrote: I don't think they do. ```suggestion ``` https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits