[clang] Add sycl_external attribute (PR #140282)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 29 12:31:47 PDT 2025
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" <sindhu.chittireddy at intel.com>
Date: Fri, 16 May 2025 08:51:06 -0700
Subject: [PATCH 1/4] 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 : SubsetSubject<Var,
def GlobalVar : SubsetSubject<Var,
[{S->hasGlobalStorage()}], "global variables">;
+
def ExternalGlobalVar : SubsetSubject<Var,
[{S->hasGlobalStorage() &&
S->getStorageClass()!=StorageClass::SC_Static &&
@@ -408,10 +409,14 @@ class SubjectList<list<AttrSubject> subjects, SubjectDiag diag = WarnDiag,
string CustomDiag = customDiag;
}
-class LangOpt<string name, code customCode = [{}]> {
+class LangOpt<string name, code customCode = [{}], bit silentlyIgnore = 0> {
// 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 : SubsetSubject<Var,
+ [{S->hasGlobalStorage() &&
+ !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 handleSYCLExternalAttr(Decl *D, const ParsedAttr &AL);
void handleKernelEntryPointAttr(Decl *D, const ParsedAttr &AL);
void CheckSYCLEntryPointFunctionDecl(FunctionDecl *FD);
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index c58cd2c93fb60..e767b79d0b25f 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -12909,6 +12909,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
if (D->hasAttr<WeakRefAttr>())
return false;
+ if (LangOpts.SYCLIsDevice && !D->hasAttr<SYCLKernelEntryPointAttr>())
+ return false;
+
// Aliases and used decls are required.
if (D->hasAttr<AliasAttr>() || D->hasAttr<UsedAttr>())
return true;
@@ -12926,6 +12929,10 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// FIXME: Functions declared with SYCL_EXTERNAL are required during
// device compilation.
+ // Functions definitions with sycl_external attribute are required during
+ // device compilation.
+ if (LangOpts.SYCLIsDevice && FD->hasAttr<SYCLExternalAttr>())
+ return true;
// Constructors and destructors are required.
if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>())
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 377595639bef1..271cf417a12f3 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -7113,6 +7113,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_SYCLKernel:
S.SYCL().handleKernelAttr(D, AL);
break;
+ case ParsedAttr::AT_SYCLExternal:
+ S.SYCL().handleSYCLExternalAttr(D, AL);
+ break;
case ParsedAttr::AT_SYCLKernelEntryPoint:
S.SYCL().handleKernelEntryPointAttr(D, AL);
break;
diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp
index 1969d7b0ba837..a08e2f076fb12 100644
--- a/clang/lib/Sema/SemaSYCL.cpp
+++ b/clang/lib/Sema/SemaSYCL.cpp
@@ -202,6 +202,17 @@ void SemaSYCL::handleKernelAttr(Decl *D, const ParsedAttr &AL) {
handleSimpleAttribute<SYCLKernelAttr>(*this, D, AL);
}
+void SemaSYCL::handleSYCLExternalAttr(Decl *D, const ParsedAttr &AL) {
+ auto *ND = cast<NamedDecl>(D);
+ if (!ND->isExternallyVisible()) {
+ Diag(AL.getLoc(), diag::err_sycl_attribute_internal_decl)
+ << AL << !isa<FunctionDecl>(ND);
+ return;
+ }
+
+ handleSimpleAttribute<SYCLExternalAttr>(*this, D, AL);
+}
+
void SemaSYCL::handleKernelEntryPointAttr(Decl *D, const ParsedAttr &AL) {
ParsedType PT = AL.getTypeArg();
TypeSourceInfo *TSI = nullptr;
diff --git a/clang/test/SemaSYCL/sycl-external-attribute.cpp b/clang/test/SemaSYCL/sycl-external-attribute.cpp
new file mode 100644
index 0000000000000..2260dba386a73
--- /dev/null
+++ b/clang/test/SemaSYCL/sycl-external-attribute.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -verify -DSYCL %s
+// RUN: %clang_cc1 -fsycl-is-host -fsyntax-only -verify -DHOST %s
+// RUN: %clang_cc1 -verify %s
+
+// Semantic tests for sycl_external attribute
+
+#ifdef SYCL
+
+__attribute__((sycl_external(3))) // expected-error {{'sycl_external' attribute takes no arguments}}
+void bar() {}
+
+__attribute__((sycl_external)) // expected-error {{'sycl_external' attribute cannot be applied to a function without external linkage}}
+static void func1() {}
+
+namespace {
+ __attribute__((sycl_external)) // expected-error {{'sycl_external' attribute cannot be applied to a function without external linkage}}
+ void func2() {}
+
+ struct UnnX {};
+}
+
+__attribute__((sycl_external)) // expected-error {{'sycl_external' attribute cannot be applied to a function without external linkage}}
+ void func4(UnnX) {}
+
+class A {
+ __attribute__((sycl_external))
+ A() {}
+
+ __attribute__((sycl_external)) void func3() {}
+};
+
+class B {
+public:
+ __attribute__((sycl_external)) virtual void foo() {}
+
+ __attribute__((sycl_external)) virtual void bar() = 0;
+};
+
+__attribute__((sycl_external)) int *func0() { return nullptr; }
+
+__attribute__((sycl_external)) void func2(int *) {}
+
+#elif defined(HOST)
+
+// expected-no-diagnostics
+__attribute__((sycl_external)) void func3() {}
+
+#else
+__attribute__((sycl_external)) // expected-warning {{'sycl_external' attribute ignored}}
+void baz() {}
+
+#endif
>From f631d7a58e5ce5e80f3562226723410af8b199d6 Mon Sep 17 00:00:00 2001
From: "Chittireddy, Sindhu" <sindhu.chittireddy at intel.com>
Date: Fri, 16 May 2025 13:48:04 -0700
Subject: [PATCH 2/4] Fix test and remove space
---
clang/include/clang/Basic/Attr.td | 1 -
clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp | 9 ++++-----
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 1c13d0eb23f3b..d2fdb1a12c9fb 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -143,7 +143,6 @@ def SharedVar : SubsetSubject<Var,
def GlobalVar : SubsetSubject<Var,
[{S->hasGlobalStorage()}], "global variables">;
-
def ExternalGlobalVar : SubsetSubject<Var,
[{S->hasGlobalStorage() &&
S->getStorageClass()!=StorageClass::SC_Static &&
diff --git a/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp b/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp
index b5687523aee36..e41209673c9cc 100644
--- a/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp
+++ b/clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp
@@ -100,11 +100,10 @@ int main() {
// Verify that SYCL kernel caller functions are emitted for each device target.
//
-// FIXME: The following set of matches are used to skip over the declaration of
-// main(). main() shouldn't be emitted in device code, but that pruning isn't
-// performed yet.
-// CHECK-DEVICE: Function Attrs: convergent mustprogress noinline norecurse nounwind optnone
-// CHECK-DEVICE-NEXT: define {{[a-z_ ]*}}noundef i32 @main() #0
+// main() shouldn't be emitted in device code. It is not annotated with
+// sycl_kernel_entry_point or sycl_external attributes.
+// Function Attrs: convergent mustprogress noinline norecurse nounwind optnone
+// CHECK-NOT: define {{[a-z_ ]*}}noundef i32 @main() #0
// IR for the SYCL kernel caller function generated for
// single_purpose_kernel_task with single_purpose_kernel_name as the SYCL kernel
>From 128ab1b1e3030b30d4b157f6657ac1c543fffb4f Mon Sep 17 00:00:00 2001
From: "Chittireddy, Sindhu" <sindhu.chittireddy at intel.com>
Date: Fri, 23 May 2025 10:46:29 -0700
Subject: [PATCH 3/4] Address review comments #1
---
clang/include/clang/Basic/Attr.td | 9 ++-------
clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 ++---
clang/include/clang/Sema/SemaSYCL.h | 2 +-
clang/lib/AST/ASTContext.cpp | 10 +++++-----
clang/lib/Sema/SemaDeclAttr.cpp | 2 +-
clang/lib/Sema/SemaSYCL.cpp | 4 ++--
6 files changed, 13 insertions(+), 19 deletions(-)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index d2fdb1a12c9fb..43a7de4257583 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -412,10 +412,6 @@ class LangOpt<string name, code customCode = [{}], bit silentlyIgnore = 0> {
// 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;
@@ -426,7 +422,6 @@ 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">;
@@ -1556,9 +1551,9 @@ def GlobalStorageNonLocalVar : SubsetSubject<Var,
"global variables">;
def SYCLExternal : InheritableAttr {
- let Spellings = [GNU<"sycl_external">];
+ let Spellings = [Clang<"sycl_external">];
let Subjects = SubjectList<[Function, GlobalStorageNonLocalVar]>;
- let LangOpts = [SYCLDevice, SilentlyIgnoreSYCLHost];
+ let LangOpts = [SYCLDevice];
let Documentation = [SYCLExternalDocs];
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9228d388bc10b..6ca2e6d6811d1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12747,9 +12747,8 @@ def err_sycl_special_type_num_init_method : Error<
"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">;
+def err_sycl_attribute_invalid_linkage : Error<
+ "'sycl_external' can only be applied to functions with external linkage">;
// SYCL kernel entry point diagnostics
def err_sycl_entry_point_invalid : Error<
diff --git a/clang/include/clang/Sema/SemaSYCL.h b/clang/include/clang/Sema/SemaSYCL.h
index 099cc56b0ef92..b1c94ee17abb2 100644
--- a/clang/include/clang/Sema/SemaSYCL.h
+++ b/clang/include/clang/Sema/SemaSYCL.h
@@ -62,7 +62,7 @@ class SemaSYCL : public SemaBase {
ParsedType ParsedTy);
void handleKernelAttr(Decl *D, const ParsedAttr &AL);
- void handleSYCLExternalAttr(Decl *D, const ParsedAttr &AL);
+ void handleExternalAttr(Decl *D, const ParsedAttr &AL);
void handleKernelEntryPointAttr(Decl *D, const ParsedAttr &AL);
void CheckSYCLEntryPointFunctionDecl(FunctionDecl *FD);
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index e767b79d0b25f..7db8a07cad603 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -12909,7 +12909,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
if (D->hasAttr<WeakRefAttr>())
return false;
- if (LangOpts.SYCLIsDevice && !D->hasAttr<SYCLKernelEntryPointAttr>())
+ if (LangOpts.SYCLIsDevice &&
+ (!D->hasAttr<SYCLKernelEntryPointAttr>() || !D->hasAttr<SYCLExternalAttr>()))
return false;
// Aliases and used decls are required.
@@ -12927,10 +12928,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
if (LangOpts.SYCLIsDevice && FD->hasAttr<SYCLKernelEntryPointAttr>())
return true;
- // FIXME: Functions declared with SYCL_EXTERNAL are required during
- // device compilation.
- // Functions definitions with sycl_external attribute are required during
- // device compilation.
+ // Functions definitions with the sycl_external attribute are required
+ // during device compilation regardless of whether they are reachable from
+ // a SYCL kernel.
if (LangOpts.SYCLIsDevice && FD->hasAttr<SYCLExternalAttr>())
return true;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 271cf417a12f3..a6996fe0ce3d1 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -7114,7 +7114,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
S.SYCL().handleKernelAttr(D, AL);
break;
case ParsedAttr::AT_SYCLExternal:
- S.SYCL().handleSYCLExternalAttr(D, AL);
+ S.SYCL().handleExternalAttr(D, AL);
break;
case ParsedAttr::AT_SYCLKernelEntryPoint:
S.SYCL().handleKernelEntryPointAttr(D, AL);
diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp
index a08e2f076fb12..c12ed801ccc97 100644
--- a/clang/lib/Sema/SemaSYCL.cpp
+++ b/clang/lib/Sema/SemaSYCL.cpp
@@ -202,10 +202,10 @@ void SemaSYCL::handleKernelAttr(Decl *D, const ParsedAttr &AL) {
handleSimpleAttribute<SYCLKernelAttr>(*this, D, AL);
}
-void SemaSYCL::handleSYCLExternalAttr(Decl *D, const ParsedAttr &AL) {
+void SemaSYCL::handleExternalAttr(Decl *D, const ParsedAttr &AL) {
auto *ND = cast<NamedDecl>(D);
if (!ND->isExternallyVisible()) {
- Diag(AL.getLoc(), diag::err_sycl_attribute_internal_decl)
+ Diag(AL.getLoc(), diag::err_sycl_attribute_invalid_linkage)
<< AL << !isa<FunctionDecl>(ND);
return;
}
>From 118656c84eba4bcc608d7c19bb7a41fa0b0fabc8 Mon Sep 17 00:00:00 2001
From: "Chittireddy, Sindhu" <sindhu.chittireddy at intel.com>
Date: Wed, 28 May 2025 12:40:52 -0700
Subject: [PATCH 4/4] Fix conditional and failing tests
---
clang/lib/AST/ASTContext.cpp | 2 +-
.../CodeGenSYCL/address-space-deduction.cpp | 2 +-
.../CodeGenSYCL/address-space-mangling.cpp | 2 +-
.../debug-info-kernel-variables.cpp | 2 +-
.../CodeGenSYCL/field-annotate-addr-space.cpp | 2 +-
.../CodeGenSYCL/functionptr-addrspace.cpp | 2 +-
.../test/SemaSYCL/sycl-external-attribute.cpp | 36 ++++++-------------
7 files changed, 17 insertions(+), 31 deletions(-)
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 7db8a07cad603..c02686800b890 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -12910,7 +12910,7 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
return false;
if (LangOpts.SYCLIsDevice &&
- (!D->hasAttr<SYCLKernelEntryPointAttr>() || !D->hasAttr<SYCLExternalAttr>()))
+ !D->hasAttr<SYCLKernelEntryPointAttr>() && !D->hasAttr<SYCLExternalAttr>())
return false;
// Aliases and used decls are required.
diff --git a/clang/test/CodeGenSYCL/address-space-deduction.cpp b/clang/test/CodeGenSYCL/address-space-deduction.cpp
index 5910ec3bfc305..0fb5c41d630cc 100644
--- a/clang/test/CodeGenSYCL/address-space-deduction.cpp
+++ b/clang/test/CodeGenSYCL/address-space-deduction.cpp
@@ -85,7 +85,7 @@
// CHECK-NEXT: store ptr addrspace(4) addrspacecast (ptr addrspace(1) @.str.1 to ptr addrspace(4)), ptr addrspace(4) [[SELECT_STR_TRIVIAL2_ASCAST]], align 8
// CHECK-NEXT: ret void
//
-void test() {
+[[clang::sycl_external]] void test() {
static const int foo = 0x42;
diff --git a/clang/test/CodeGenSYCL/address-space-mangling.cpp b/clang/test/CodeGenSYCL/address-space-mangling.cpp
index 868bf8ccbdcf8..ecc2d4b43a159 100644
--- a/clang/test/CodeGenSYCL/address-space-mangling.cpp
+++ b/clang/test/CodeGenSYCL/address-space-mangling.cpp
@@ -18,7 +18,7 @@ void foo(int *);
// X86: declare void @_Z3fooPU9SYprivatei(ptr noundef) #1
// X86: declare void @_Z3fooPi(ptr noundef) #1
-void test() {
+[[clang::sycl_external]] void test() {
__attribute__((opencl_global)) int *glob;
__attribute__((opencl_local)) int *loc;
__attribute__((opencl_private)) int *priv;
diff --git a/clang/test/CodeGenSYCL/debug-info-kernel-variables.cpp b/clang/test/CodeGenSYCL/debug-info-kernel-variables.cpp
index 96c0dcfdb75b6..551c4e7e2b8b4 100644
--- a/clang/test/CodeGenSYCL/debug-info-kernel-variables.cpp
+++ b/clang/test/CodeGenSYCL/debug-info-kernel-variables.cpp
@@ -18,7 +18,7 @@ KERNEL void parallel_for(const KernelType &KernelFunc) {
KernelFunc();
}
-void my_kernel(int my_param) {
+[[clang::sycl_external]] void my_kernel(int my_param) {
int my_local = 0;
my_local = my_param;
}
diff --git a/clang/test/CodeGenSYCL/field-annotate-addr-space.cpp b/clang/test/CodeGenSYCL/field-annotate-addr-space.cpp
index 26bfda8185112..fe7a160900a54 100644
--- a/clang/test/CodeGenSYCL/field-annotate-addr-space.cpp
+++ b/clang/test/CodeGenSYCL/field-annotate-addr-space.cpp
@@ -9,7 +9,7 @@ struct HasField {
int *a;
};
-void foo(int *b) {
+[[clang::sycl_external]] void foo(int *b) {
struct HasField f;
// CHECK: %[[A:.+]] = getelementptr inbounds nuw %struct.HasField, ptr addrspace(4) %{{.+}}
// CHECK: %[[CALL:.+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p1(ptr addrspace(4) %[[A]], ptr addrspace(1) [[ANNOT]]
diff --git a/clang/test/CodeGenSYCL/functionptr-addrspace.cpp b/clang/test/CodeGenSYCL/functionptr-addrspace.cpp
index a477b4c7d03ab..060104a29b60a 100644
--- a/clang/test/CodeGenSYCL/functionptr-addrspace.cpp
+++ b/clang/test/CodeGenSYCL/functionptr-addrspace.cpp
@@ -8,7 +8,7 @@ __attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
}
// CHECK: define dso_local spir_func{{.*}}invoke_function{{.*}}(ptr noundef %fptr, ptr addrspace(4) noundef %ptr)
-void invoke_function(int (*fptr)(), int *ptr) {}
+[[clang::sycl_external]] void invoke_function(int (*fptr)(), int *ptr) {}
int f() { return 0; }
diff --git a/clang/test/SemaSYCL/sycl-external-attribute.cpp b/clang/test/SemaSYCL/sycl-external-attribute.cpp
index 2260dba386a73..4bf40c37400ea 100644
--- a/clang/test/SemaSYCL/sycl-external-attribute.cpp
+++ b/clang/test/SemaSYCL/sycl-external-attribute.cpp
@@ -1,52 +1,38 @@
-// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -verify -DSYCL %s
-// RUN: %clang_cc1 -fsycl-is-host -fsyntax-only -verify -DHOST %s
-// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -verify %s
// Semantic tests for sycl_external attribute
-#ifdef SYCL
-
-__attribute__((sycl_external(3))) // expected-error {{'sycl_external' attribute takes no arguments}}
+[[clang::sycl_external(3)]] // expected-error {{'sycl_external' attribute takes no arguments}}
void bar() {}
-__attribute__((sycl_external)) // expected-error {{'sycl_external' attribute cannot be applied to a function without external linkage}}
+[[clang::sycl_external]] // expected-error {{'sycl_external' can only be applied to functions with external linkage}}
static void func1() {}
namespace {
- __attribute__((sycl_external)) // expected-error {{'sycl_external' attribute cannot be applied to a function without external linkage}}
+ [[clang::sycl_external]] // expected-error {{'sycl_external' can only be applied to functions with external linkage}}
void func2() {}
struct UnnX {};
}
-__attribute__((sycl_external)) // expected-error {{'sycl_external' attribute cannot be applied to a function without external linkage}}
+[[clang::sycl_external]] // expected-error {{'sycl_external' can only be applied to functions with external linkage}}
void func4(UnnX) {}
class A {
- __attribute__((sycl_external))
+ [[clang::sycl_external]]
A() {}
- __attribute__((sycl_external)) void func3() {}
+ [[clang::sycl_external]] void func3() {}
};
class B {
public:
- __attribute__((sycl_external)) virtual void foo() {}
+ [[clang::sycl_external]] virtual void foo() {}
- __attribute__((sycl_external)) virtual void bar() = 0;
+ [[clang::sycl_external]] virtual void bar() = 0;
};
-__attribute__((sycl_external)) int *func0() { return nullptr; }
-
-__attribute__((sycl_external)) void func2(int *) {}
-
-#elif defined(HOST)
-
-// expected-no-diagnostics
-__attribute__((sycl_external)) void func3() {}
+[[clang::sycl_external]] int *func0() { return nullptr; }
-#else
-__attribute__((sycl_external)) // expected-warning {{'sycl_external' attribute ignored}}
-void baz() {}
+[[clang::sycl_external]] void func2(int *) {}
-#endif
More information about the cfe-commits
mailing list