[clang] [llvm] [clang] Check validity of SYCL device target (PR #172366)
via cfe-commits
cfe-commits at lists.llvm.org
Wed May 6 08:57:58 PDT 2026
https://github.com/elizabethandrews updated https://github.com/llvm/llvm-project/pull/172366
>From 40d639f37365d691c6f9783b8686da404a2f63d1 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Mon, 8 Dec 2025 11:39:23 -0800
Subject: [PATCH 1/6] Add a check for the validity of device target in SYCL
device compilation.
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++
clang/include/clang/Basic/TargetInfo.h | 4 ++++
clang/lib/Basic/Targets.cpp | 2 ++
clang/lib/Basic/Targets/AMDGPU.h | 2 ++
clang/lib/Basic/Targets/NVPTX.h | 1 +
clang/lib/Basic/Targets/SPIR.h | 2 ++
clang/lib/Frontend/CompilerInstance.cpp | 6 ++++++
clang/lib/Frontend/CompilerInvocation.cpp | 5 +++++
clang/test/AST/ByteCode/sycl.cpp | 4 ++--
clang/test/ASTSYCL/ast-dump-sycl-kernel-call-stmt.cpp | 6 +++---
.../test/ASTSYCL/ast-dump-sycl-kernel-entry-point.cpp | 6 +++---
clang/test/CodeGenSYCL/address-space-mangling.cpp | 6 ------
clang/test/Frontend/check-sycl-device-target.cpp | 10 ++++++++++
clang/test/SemaSYCL/float128.cpp | 1 -
.../sycl-kernel-entry-point-attr-appertainment.cpp | 11 +++--------
.../SemaSYCL/sycl-kernel-entry-point-attr-grammar.cpp | 4 ++--
.../sycl-kernel-entry-point-attr-kernel-name.cpp | 4 ++--
.../SemaSYCL/sycl-kernel-entry-point-attr-sfinae.cpp | 4 ++--
.../unique-stable-name-multiple-target-crash.cpp | 2 +-
clang/test/SemaSYCL/unique_stable_name.cpp | 3 +--
20 files changed, 53 insertions(+), 32 deletions(-)
create mode 100644 clang/test/Frontend/check-sycl-device-target.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 381d1fb063eba..a027bf8152e89 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13149,6 +13149,8 @@ def warn_sycl_kernel_return_type : Warning<
def err_sycl_special_type_num_init_method : Error<
"types with 'sycl_special_class' attribute must have one and only one '__init' "
"method defined">;
+def err_sycl_device_invalid_target : Error<
+ "%0 is not a supported SYCL device target">;
// SYCL external attribute diagnostics
def err_sycl_external_invalid_linkage : Error<
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 4ff77bb64cf1c..699253248443c 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1903,6 +1903,10 @@ class TargetInfo : public TransferrableTargetInfo,
virtual bool validateOpenCLTarget(const LangOptions &Opts,
DiagnosticsEngine &Diags) const;
+ /// Determine whether the specified target is a valid target
+ /// for SYCL device compilation. The default is false.
+ virtual bool isValidSYCLDeviceTarget() const;
+
virtual void setAuxTarget(const TargetInfo *Aux) {}
bool hasMicrosoftRecordLayout() const { return HasMicrosoftRecordLayout; }
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 38eb1edd4bfb7..23ba1fd856667 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -901,3 +901,5 @@ bool TargetInfo::validateOpenCLTarget(const LangOptions &Opts,
return OpenCLOptions::diagnoseUnsupportedFeatureDependencies(*this, Diags) &&
OpenCLOptions::diagnoseFeatureExtensionDifferences(*this, Diags);
}
+
+bool TargetInfo::isValidSYCLDeviceTarget() const { return false; }
diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
index 0076f822c02a1..d0cbf7da75ef2 100644
--- a/clang/lib/Basic/Targets/AMDGPU.h
+++ b/clang/lib/Basic/Targets/AMDGPU.h
@@ -496,6 +496,8 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
bool hasHIPImageSupport() const override { return HasImage; }
+ bool isValidSYCLDeviceTarget() const override { return true; }
+
std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
// This is imprecise as the value can vary between 64, 128 (even 256!) bytes
// depending on the level of cache and the target architecture. We select
diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index f5c8396f398aa..393958128758c 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -205,6 +205,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
bool hasBitIntType() const override { return true; }
bool hasBFloat16Type() const override { return true; }
+ bool isValidSYCLDeviceTarget() const override { return true; }
OffloadArch getGPU() const { return GPU; }
};
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index a9fc62812b1e3..b01e3c421ea43 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -239,6 +239,8 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
bool hasBitIntType() const override { return true; }
bool hasInt128Type() const override { return false; }
+
+ bool isValidSYCLDeviceTarget() const override { return true; }
};
class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index f7f0ea3317932..59e46a9accc6d 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -114,6 +114,12 @@ bool CompilerInstance::createTarget() {
if (!hasTarget())
return false;
+ if (getLangOpts().SYCLIsDevice && !getTarget().isValidSYCLDeviceTarget()) {
+ getDiagnostics().Report(diag::err_sycl_device_invalid_target)
+ << getTarget().getTriple().str();
+ return false;
+ }
+
// Check whether AuxTarget exists, if not, then create TargetInfo for the
// other side of CUDA/OpenMP/SYCL compilation.
if (!getAuxTarget() &&
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 477406f2526c0..e1c86b3a2eabe 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -5074,6 +5074,11 @@ bool CompilerInvocation::CreateFromArgsImpl(
if (LangOpts.OpenMPIsTargetDevice)
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
+ // Set the default triple for SYCL device compilation.
+ if (LangOpts.SYCLIsDevice && !Args.hasArg(options::OPT_triple)) {
+ Res.getTargetOpts().Triple = "spirv64-unknown-unknown";
+ }
+
ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
Res.getFrontendOpts().OutputFile, LangOpts);
diff --git a/clang/test/AST/ByteCode/sycl.cpp b/clang/test/AST/ByteCode/sycl.cpp
index 5c922eca58091..dfd62508fb6a3 100644
--- a/clang/test/AST/ByteCode/sycl.cpp
+++ b/clang/test/AST/ByteCode/sycl.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -std=c++17 -triple x86_64-linux-gnu -fsycl-is-device -verify=both,ref -fsyntax-only -Wno-unused
-// RUN: %clang_cc1 %s -std=c++17 -triple x86_64-linux-gnu -fsycl-is-device -verify=both,expected -fsyntax-only -Wno-unused -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 %s -std=c++17 -triple spirv64-unknown-unknown -fsycl-is-device -verify=both,ref -fsyntax-only -Wno-unused
+// RUN: %clang_cc1 %s -std=c++17 -triple spirv64-unknown-unknown -fsycl-is-device -verify=both,expected -fsyntax-only -Wno-unused -fexperimental-new-constant-interpreter
// both-no-diagnostics
diff --git a/clang/test/ASTSYCL/ast-dump-sycl-kernel-call-stmt.cpp b/clang/test/ASTSYCL/ast-dump-sycl-kernel-call-stmt.cpp
index e3ff3dea19514..b8b3e9c3c5119 100644
--- a/clang/test/ASTSYCL/ast-dump-sycl-kernel-call-stmt.cpp
+++ b/clang/test/ASTSYCL/ast-dump-sycl-kernel-call-stmt.cpp
@@ -1,5 +1,5 @@
// Tests without serialization:
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \
+// RUN: %clang_cc1 -std=c++17 -triple spirv64-unknown-unknown -fsycl-is-device \
// RUN: -ast-dump %s \
// RUN: | FileCheck --match-full-lines %s
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-host \
@@ -7,9 +7,9 @@
// RUN: | FileCheck --match-full-lines %s
//
// Tests with serialization:
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \
+// RUN: %clang_cc1 -std=c++17 -triple spirv64-unknown-unknown -fsycl-is-device \
// RUN: -emit-pch -o %t %s
-// RUN: %clang_cc1 -x c++ -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \
+// RUN: %clang_cc1 -x c++ -std=c++17 -triple spirv64-unknown-unknown -fsycl-is-device \
// RUN: -include-pch %t -ast-dump-all /dev/null \
// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
// RUN: | FileCheck --match-full-lines %s
diff --git a/clang/test/ASTSYCL/ast-dump-sycl-kernel-entry-point.cpp b/clang/test/ASTSYCL/ast-dump-sycl-kernel-entry-point.cpp
index 0171f72df0b37..ecbf199298d20 100644
--- a/clang/test/ASTSYCL/ast-dump-sycl-kernel-entry-point.cpp
+++ b/clang/test/ASTSYCL/ast-dump-sycl-kernel-entry-point.cpp
@@ -1,5 +1,5 @@
// Tests without serialization:
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \
+// RUN: %clang_cc1 -std=c++17 -triple spirv64-unknown-unknown -fsycl-is-device \
// RUN: -ast-dump %s \
// RUN: | FileCheck --match-full-lines %s
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-host \
@@ -7,9 +7,9 @@
// RUN: | FileCheck --match-full-lines %s
//
// Tests with serialization:
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \
+// RUN: %clang_cc1 -std=c++17 -triple spirv64-unknown-unknown -fsycl-is-device \
// RUN: -emit-pch -o %t %s
-// RUN: %clang_cc1 -x c++ -std=c++17 -triple x86_64-unknown-unknown -fsycl-is-device \
+// RUN: %clang_cc1 -x c++ -std=c++17 -triple spirv64-unknown-unknown -fsycl-is-device \
// RUN: -include-pch %t -ast-dump-all /dev/null \
// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
// RUN: | FileCheck --match-full-lines %s
diff --git a/clang/test/CodeGenSYCL/address-space-mangling.cpp b/clang/test/CodeGenSYCL/address-space-mangling.cpp
index ecc2d4b43a159..5d011e9770bb0 100644
--- a/clang/test/CodeGenSYCL/address-space-mangling.cpp
+++ b/clang/test/CodeGenSYCL/address-space-mangling.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -triple spir64 -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=SPIR
-// RUN: %clang_cc1 -triple x86_64 -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=X86
// REQUIRES: x86-registered-target
@@ -13,11 +12,6 @@ void foo(int *);
// SPIR: declare spir_func void @_Z3fooPU3AS0i(ptr noundef) #1
// SPIR: declare spir_func void @_Z3fooPi(ptr addrspace(4) noundef) #1
-// X86: declare void @_Z3fooPU8SYglobali(ptr noundef) #1
-// X86: declare void @_Z3fooPU7SYlocali(ptr noundef) #1
-// X86: declare void @_Z3fooPU9SYprivatei(ptr noundef) #1
-// X86: declare void @_Z3fooPi(ptr noundef) #1
-
[[clang::sycl_external]] void test() {
__attribute__((opencl_global)) int *glob;
__attribute__((opencl_local)) int *loc;
diff --git a/clang/test/Frontend/check-sycl-device-target.cpp b/clang/test/Frontend/check-sycl-device-target.cpp
new file mode 100644
index 0000000000000..3554d8f91d000
--- /dev/null
+++ b/clang/test/Frontend/check-sycl-device-target.cpp
@@ -0,0 +1,10 @@
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -fsycl-is-device %s 2>&1 | FileCheck --check-prefixes=INVALID %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsyntax-only -fsycl-is-device -verify=valid %s
+// RUN: %clang_cc1 -fsyntax-only -fsycl-is-device -verify=valid %s
+
+// These tests validate the target for SYCL device compilation
+
+// INVALID: 86_64-unknown-unknown is not a supported SYCL device target
+
+// valid-no-diagnostics
+
diff --git a/clang/test/SemaSYCL/float128.cpp b/clang/test/SemaSYCL/float128.cpp
index e41dea38dbe75..9841d620ebc22 100644
--- a/clang/test/SemaSYCL/float128.cpp
+++ b/clang/test/SemaSYCL/float128.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -triple spir64 -fsycl-is-device -verify -fsyntax-only %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsycl-is-device -fsyntax-only %s
typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
typedef __float128 BIGTY;
diff --git a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-appertainment.cpp b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-appertainment.cpp
index 9aba284145fcb..f5f327216e91c 100644
--- a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-appertainment.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-appertainment.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 -fsyntax-only -fsycl-is-device -verify %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++20 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++23 -fsyntax-only -fsycl-is-device -verify %s
// These tests validate appertainment for the sycl_kernel_entry_point attribute.
@@ -277,11 +277,6 @@ consteval void bad25() {}
[[clang::sycl_kernel_entry_point(BADKN<26>)]]
[[noreturn]] void bad26();
-// expected-error at +3 {{attribute 'target' multiversioning cannot be combined with attribute 'clang::sycl_kernel_entry_point'}}
-__attribute__((target("avx"))) void bad27();
-[[clang::sycl_kernel_entry_point(BADKN<27>)]]
-__attribute__((target("sse4.2"))) void bad27();
-
template<typename KNT>
struct B28 {
// expected-error at +1 {{the 'clang::sycl_kernel_entry_point' attribute cannot be applied to a deleted function}}
diff --git a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-grammar.cpp b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-grammar.cpp
index 8f81fa218c171..0f7317befaa9f 100644
--- a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-grammar.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-grammar.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++20 -fsyntax-only -fsycl-is-device -verify %s
// These tests validate parsing of the sycl_kernel_entry_point argument list
// and that the single argument names a type.
diff --git a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-kernel-name.cpp b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-kernel-name.cpp
index c7b83932fefe6..303453aec208f 100644
--- a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-kernel-name.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-kernel-name.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++20 -fsyntax-only -fsycl-is-device -verify %s
// These tests validate that the kernel name type argument provided to the
// sycl_kernel_entry_point attribute meets the requirements of a SYCL kernel
diff --git a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-sfinae.cpp b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-sfinae.cpp
index 4c61570419629..c95e1a9ffd1ab 100644
--- a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-sfinae.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-sfinae.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++20 -fsyntax-only -fsycl-is-device -verify %s
// These tests are intended to validate that a sycl_kernel_entry_point attribute
// appearing in the declaration of a function template does not affect overload
diff --git a/clang/test/SemaSYCL/unique-stable-name-multiple-target-crash.cpp b/clang/test/SemaSYCL/unique-stable-name-multiple-target-crash.cpp
index ec78feac8b7b3..5ec1b8120ebfa 100644
--- a/clang/test/SemaSYCL/unique-stable-name-multiple-target-crash.cpp
+++ b/clang/test/SemaSYCL/unique-stable-name-multiple-target-crash.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s %s -std=c++17 -triple x86_64-linux-gnu -fsycl-is-device -verify -fsyntax-only -Wno-unused
+// RUN: %clang_cc1 %s %s -std=c++17 -triple spirv64-unknown-unknown -fsycl-is-device -verify -fsyntax-only -Wno-unused
// This would crash due to the double-inputs, since the 'magic static' use in
// the AST Context SCYL Filtering would end up caching an old version of the
diff --git a/clang/test/SemaSYCL/unique_stable_name.cpp b/clang/test/SemaSYCL/unique_stable_name.cpp
index fb3b0dbe9e0ee..15f64cc556845 100644
--- a/clang/test/SemaSYCL/unique_stable_name.cpp
+++ b/clang/test/SemaSYCL/unique_stable_name.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 %s -std=c++17 -triple x86_64-pc-windows-msvc -fsycl-is-device -verify -fsyntax-only -Wno-unused
-// RUN: %clang_cc1 %s -std=c++17 -triple x86_64-linux-gnu -fsycl-is-device -verify -fsyntax-only -Wno-unused
+// RUN: %clang_cc1 %s -std=c++17 -triple spirv64-unknown-unknown -fsycl-is-device -verify -fsyntax-only -Wno-unused
template <typename KernelName, typename KernelType>
[[clang::sycl_kernel]] void kernel_single_task(KernelType kernelFunc) { // #kernelSingleTask
>From ce5db87ad93d1e8f6cd624cc841b9de84418aee8 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Fri, 19 Dec 2025 07:38:12 -0800
Subject: [PATCH 2/6] Apply review comments
---
clang/lib/Frontend/CompilerInvocation.cpp | 3 +--
clang/test/Frontend/check-sycl-device-target.cpp | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index e1c86b3a2eabe..ff5d23bada996 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -5075,9 +5075,8 @@ bool CompilerInvocation::CreateFromArgsImpl(
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
// Set the default triple for SYCL device compilation.
- if (LangOpts.SYCLIsDevice && !Args.hasArg(options::OPT_triple)) {
+ if (LangOpts.SYCLIsDevice && !Args.hasArg(options::OPT_triple))
Res.getTargetOpts().Triple = "spirv64-unknown-unknown";
- }
ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
Res.getFrontendOpts().OutputFile, LangOpts);
diff --git a/clang/test/Frontend/check-sycl-device-target.cpp b/clang/test/Frontend/check-sycl-device-target.cpp
index 3554d8f91d000..9e75a4b99ef61 100644
--- a/clang/test/Frontend/check-sycl-device-target.cpp
+++ b/clang/test/Frontend/check-sycl-device-target.cpp
@@ -4,7 +4,7 @@
// These tests validate the target for SYCL device compilation
-// INVALID: 86_64-unknown-unknown is not a supported SYCL device target
+// INVALID: x86_64-unknown-unknown is not a supported SYCL device target
// valid-no-diagnostics
>From 77d21c19dd1740abd9a8b8589dfef0bc0d442d35 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Fri, 19 Dec 2025 11:00:04 -0800
Subject: [PATCH 3/6] Add driver test
---
clang/test/Driver/sycl-device.cpp | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 clang/test/Driver/sycl-device.cpp
diff --git a/clang/test/Driver/sycl-device.cpp b/clang/test/Driver/sycl-device.cpp
new file mode 100644
index 0000000000000..9971a75109ebf
--- /dev/null
+++ b/clang/test/Driver/sycl-device.cpp
@@ -0,0 +1,16 @@
+/// Check "-fsycl-is-device" and the default triple "spirv64-unknown-unknown"
+// is passed when compiling for device.
+
+// RUN: %clang -### -fsycl -fsycl-device-only %s 2>&1 \
+// RUN: | FileCheck %s
+
+// CHECK: "-triple" "spirv64-unknown-unknown" {{.*}} "-fsycl-is-device"
+
+/// Check "-fsycl-is-device" and explicitly specified triple "nvptx" is
+// passed when compiling for device.
+
+// RUN: %clang -### -fsycl -fsycl-device-only --target=nvptx %s 2>&1 \
+// RUN: | FileCheck %s -check-prefix=TARGET
+//
+// TARGET: "-triple" "spirv32-unknown-unknown" "-aux-triple" "nvptx"
+
>From c8d957c938a08e7ff0dfdf732257abe9c7937d11 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Fri, 10 Apr 2026 15:30:02 -0700
Subject: [PATCH 4/6] Fix tests
---
.../sycl-kernel-entry-point-attr-device-odr-use.cpp | 2 +-
clang/test/SemaSYCL/sycl-kernel-entry-point-attr-this.cpp | 6 +++---
clang/test/SemaSYCL/sycl-kernel-launch-ms-compat.cpp | 2 +-
clang/test/SemaSYCL/sycl-kernel-launch.cpp | 6 +++---
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-device-odr-use.cpp b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-device-odr-use.cpp
index e2854983da552..631e1d7ad3870 100644
--- a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-device-odr-use.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-device-odr-use.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsycl-is-host -verify=host %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsycl-is-device -verify=device %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++17 -fsycl-is-device -verify=device %s
// These tests validate that a diagnostic is issued if a function declared with
// the sycl_kernel_entry_point attribute is ODR-used from code that is emitted
diff --git a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-this.cpp b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-this.cpp
index 2112733b41fc6..ac2d5c1541528 100644
--- a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-this.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-this.cpp
@@ -1,9 +1,9 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -std=c++17 -fsycl-is-host -verify %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -std=c++17 -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsyntax-only -std=c++17 -fsycl-is-device -verify %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -std=c++20 -fsycl-is-host -verify %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -std=c++20 -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsyntax-only -std=c++20 -fsycl-is-device -verify %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -std=c++23 -fsycl-is-host -verify %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -std=c++23 -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsyntax-only -std=c++23 -fsycl-is-device -verify %s
// These tests validate diagnostics for invalid use of 'this' in the body of
// a function declared with the sycl_kernel_entry_point attribute.
diff --git a/clang/test/SemaSYCL/sycl-kernel-launch-ms-compat.cpp b/clang/test/SemaSYCL/sycl-kernel-launch-ms-compat.cpp
index cd186a833b024..f62b129273217 100644
--- a/clang/test/SemaSYCL/sycl-kernel-launch-ms-compat.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-launch-ms-compat.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++20 -fsyntax-only -fsycl-is-host -fms-compatibility -fcxx-exceptions -verify=host,expected %s
-// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++20 -fsyntax-only -fsycl-is-device -fms-compatibility -verify=device,expected %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++20 -fsyntax-only -fsycl-is-device -fms-compatibility -verify=device,expected %s
// Test Microsoft extensions for lookup of a sycl_kernel_launch member template
// in a dependent base class.
diff --git a/clang/test/SemaSYCL/sycl-kernel-launch.cpp b/clang/test/SemaSYCL/sycl-kernel-launch.cpp
index 20d9becb81929..23c1209492c60 100644
--- a/clang/test/SemaSYCL/sycl-kernel-launch.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-launch.cpp
@@ -1,9 +1,9 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsyntax-only -fsycl-is-host -fcxx-exceptions -verify %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 -fsyntax-only -fsycl-is-host -fcxx-exceptions -verify %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++20 -fsyntax-only -fsycl-is-device -verify %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -fsycl-is-host -fcxx-exceptions -verify %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -std=c++23 -fsyntax-only -fsycl-is-device -verify %s
// Test overload resolution for implicit calls to sycl_kernel_launch<KN>(...)
// synthesized for functions declared with the sycl_kernel_entry_point
>From 6ce324ad6e1ef1f656d512ea2ddd730cba48f4d4 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Thu, 30 Apr 2026 11:07:46 -0700
Subject: [PATCH 5/6] USe isGPU() instead of adding isValidSYCLDeviceTarget()
---
clang/include/clang/Basic/TargetInfo.h | 4 ----
clang/lib/Basic/Targets.cpp | 2 --
clang/lib/Basic/Targets/AMDGPU.h | 2 --
clang/lib/Basic/Targets/NVPTX.h | 1 -
clang/lib/Basic/Targets/SPIR.h | 1 -
clang/lib/Frontend/CompilerInstance.cpp | 2 +-
.../sycl-kernel-entry-point-attr-appertainment.cpp | 7 +++++++
llvm/include/llvm/TargetParser/Triple.h | 2 +-
8 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 7a668d4809aab..9f7d2a17a0f8a 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1913,10 +1913,6 @@ class TargetInfo : public TransferrableTargetInfo,
virtual bool validateOpenCLTarget(const LangOptions &Opts,
DiagnosticsEngine &Diags) const;
- /// Determine whether the specified target is a valid target
- /// for SYCL device compilation. The default is false.
- virtual bool isValidSYCLDeviceTarget() const;
-
virtual void setAuxTarget(const TargetInfo *Aux) {}
bool hasMicrosoftRecordLayout() const { return HasMicrosoftRecordLayout; }
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 7e3e85fab94c8..dc6ef6ed8f3f8 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -919,5 +919,3 @@ bool TargetInfo::validateOpenCLTarget(const LangOptions &Opts,
return OpenCLOptions::diagnoseUnsupportedFeatureDependencies(*this, Diags) &&
OpenCLOptions::diagnoseFeatureExtensionDifferences(*this, Diags);
}
-
-bool TargetInfo::isValidSYCLDeviceTarget() const { return false; }
diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
index aeef3a3c34501..38c92e73708f8 100644
--- a/clang/lib/Basic/Targets/AMDGPU.h
+++ b/clang/lib/Basic/Targets/AMDGPU.h
@@ -501,8 +501,6 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
bool hasHIPImageSupport() const override { return HasImage; }
- bool isValidSYCLDeviceTarget() const override { return true; }
-
std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
// This is imprecise as the value can vary between 64, 128 (even 256!) bytes
// depending on the level of cache and the target architecture. We select
diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index a04ab1a9cdbb6..69ee20f38343b 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -217,7 +217,6 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
bool hasBitIntType() const override { return true; }
bool hasBFloat16Type() const override { return true; }
- bool isValidSYCLDeviceTarget() const override { return true; }
OffloadArch getGPU() const { return GPU; }
};
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 8f918ed2a78ef..05ef8c6eeda2b 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -245,7 +245,6 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
bool hasInt128Type() const override { return false; }
- bool isValidSYCLDeviceTarget() const override { return true; }
};
class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 43cf58a981624..8533293b8994a 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -118,7 +118,7 @@ bool CompilerInstance::createTarget() {
if (!hasTarget())
return false;
- if (getLangOpts().SYCLIsDevice && !getTarget().isValidSYCLDeviceTarget()) {
+ if (getLangOpts().SYCLIsDevice && !getTarget().getTriple().isGPU()) {
getDiagnostics().Report(diag::err_sycl_device_invalid_target)
<< getTarget().getTriple().str();
return false;
diff --git a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-appertainment.cpp b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-appertainment.cpp
index 0648583b31681..18118fc43a602 100644
--- a/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-appertainment.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-entry-point-attr-appertainment.cpp
@@ -286,6 +286,13 @@ consteval void bad25() {}
[[clang::sycl_kernel_entry_point(BADKN<26>)]]
[[noreturn]] void bad26();
+#if !defined(__SYCL_DEVICE_ONLY__)
+// expected-error at +3 {{attribute 'target' multiversioning cannot be combined with attribute 'clang::sycl_kernel_entry_point'}}
+__attribute__((target("avx"))) void bad27();
+[[clang::sycl_kernel_entry_point(BADKN<27>)]]
+__attribute__((target("sse4.2"))) void bad27();
+#endif
+
template<typename KNT>
struct B28 {
// expected-error at +1 {{the 'clang::sycl_kernel_entry_point' attribute cannot be applied to a deleted function}}
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 7c5aa52a1bd04..859a26ee13417 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -1342,7 +1342,7 @@ class Triple {
LLVM_ABI bool isCompatibleWith(const Triple &Other) const;
/// Test whether the target triple is for a GPU.
- bool isGPU() const { return isSPIRV() || isNVPTX() || isAMDGPU(); }
+ bool isGPU() const { return isSPIROrSPIRV() || isNVPTX() || isAMDGPU(); }
/// Merge target triples.
LLVM_ABI std::string merge(const Triple &Other) const;
>From 5476277e725cd5cc7334337a01b5f85f1a130b70 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <elizabeth.andrews at intel.com>
Date: Wed, 6 May 2026 08:56:58 -0700
Subject: [PATCH 6/6] Set HostTriple to inherit type properties from host
architecture
---
.../include/clang/Frontend/FrontendOptions.h | 2 +-
clang/lib/Driver/ToolChains/Clang.cpp | 2 +-
clang/lib/Frontend/CompilerInvocation.cpp | 9 +++++---
clang/test/Driver/sycl-device.cpp | 16 --------------
clang/test/SemaSYCL/aux-triple.cpp | 22 +++++++++++++++++++
5 files changed, 30 insertions(+), 21 deletions(-)
delete mode 100644 clang/test/Driver/sycl-device.cpp
create mode 100644 clang/test/SemaSYCL/aux-triple.cpp
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index f7f51bc37c98d..2f75fba566dfb 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -513,7 +513,7 @@ class FrontendOptions {
/// (in the format produced by -fdump-record-layouts).
std::string OverrideRecordLayoutsFile;
- /// Auxiliary triple for CUDA/HIP compilation.
+ /// Auxiliary triple for CUDA/HIP/SYCL compilation.
std::string AuxTriple;
/// Auxiliary target CPU for CUDA/HIP compilation.
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index f685abe9dad35..0e8ac403fa4cf 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4998,7 +4998,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
const llvm::Triple *AuxTriple =
- (IsCuda || IsHIP) ? TC.getAuxTriple() : nullptr;
+ (IsCuda || IsHIP || IsSYCLDevice) ? TC.getAuxTriple() : nullptr;
bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
bool IsUEFI = RawTriple.isUEFI();
bool IsIAMCU = RawTriple.isOSIAMCU();
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 87caf44deaf5b..c9b38a35c1e14 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -5111,9 +5111,12 @@ bool CompilerInvocation::CreateFromArgsImpl(
if (LangOpts.OpenMPIsTargetDevice)
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
- // Set the default triple for SYCL device compilation.
- if (LangOpts.SYCLIsDevice && !Args.hasArg(options::OPT_triple))
- Res.getTargetOpts().Triple = "spirv64-unknown-unknown";
+ // Set the default and host triples for SYCL device compilation.
+ if (LangOpts.SYCLIsDevice) {
+ if (!Args.hasArg(options::OPT_triple))
+ Res.getTargetOpts().Triple = "spirv64-unknown-unknown";
+ Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
+ }
ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
Res.getFrontendOpts().OutputFile, LangOpts);
diff --git a/clang/test/Driver/sycl-device.cpp b/clang/test/Driver/sycl-device.cpp
deleted file mode 100644
index 9971a75109ebf..0000000000000
--- a/clang/test/Driver/sycl-device.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-/// Check "-fsycl-is-device" and the default triple "spirv64-unknown-unknown"
-// is passed when compiling for device.
-
-// RUN: %clang -### -fsycl -fsycl-device-only %s 2>&1 \
-// RUN: | FileCheck %s
-
-// CHECK: "-triple" "spirv64-unknown-unknown" {{.*}} "-fsycl-is-device"
-
-/// Check "-fsycl-is-device" and explicitly specified triple "nvptx" is
-// passed when compiling for device.
-
-// RUN: %clang -### -fsycl -fsycl-device-only --target=nvptx %s 2>&1 \
-// RUN: | FileCheck %s -check-prefix=TARGET
-//
-// TARGET: "-triple" "spirv32-unknown-unknown" "-aux-triple" "nvptx"
-
diff --git a/clang/test/SemaSYCL/aux-triple.cpp b/clang/test/SemaSYCL/aux-triple.cpp
new file mode 100644
index 0000000000000..34c45b7d2a5ec
--- /dev/null
+++ b/clang/test/SemaSYCL/aux-triple.cpp
@@ -0,0 +1,22 @@
+// Test that SYCL device compilation inherits type properties from the host
+// architecture via AuxTriple/HostTriple.
+
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown \
+// RUN: -aux-triple x86_64-unknown-linux-gnu -fsycl-is-device \
+// RUN: -fsyntax-only -verify=linux %s
+
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown \
+// RUN: -aux-triple x86_64-pc-windows-msvc -fsycl-is-device \
+// RUN: -fsyntax-only -verify=windows %s
+
+// linux-no-diagnostics
+// windows-no-diagnostics
+
+void test_long_size() {
+#if defined(_WIN64)
+ static_assert(sizeof(long) == 4, "long should be 4 bytes on Windows");
+#else
+ static_assert(sizeof(long) == 8, "long should be 8 bytes on Linux");
+#endif
+}
+
More information about the cfe-commits
mailing list