https://github.com/srividya-sundaram updated https://github.com/llvm/llvm-project/pull/229249
>From 162e5ec9b56859055a03fa4c6cc4420d4ce6a09d Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Fri, 30 Oct 2026 11:36:54 -0700 Subject: [PATCH 1/9] [Clang][SYCL] Infer the SPIR-V target from an Intel offload architecture For SYCL, an Intel GPU or CPU name, an IGCA target or "generic" in --offload-arch now selects spirv64-unknown-unknown on a 64-bit host and spirv32-unknown-unknown otherwise, so --offload-targets is no longer needed. --- clang/docs/ReleaseNotes.md | 4 +++ clang/lib/Driver/Driver.cpp | 17 +++++++--- clang/test/Driver/sycl-intel-gpu-arch.cpp | 38 +++++++++++++++++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 4b9e9228380d1d..ab3762e4473c52 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -1532,6 +1532,10 @@ The `alpha.cplusplus.UseAfterLifetimeEnd` checker was renamed to `alpha.core.Use #### Improvements +- `-fsycl --offload-arch=<arch>` now selects the SPIR-V target without + `--offload-targets` when `<arch>` is an Intel GPU (e.g. `xe-pvc`), an IGCA + target (e.g. `igca_20ca`) or `generic`. + ### Clang IR Improvements - Clang builds now build ClangIR support by default. Clang IR is expected to work with most Linux/X86-64 workloads. Normal builds are unchanged, however those who wish to test out the experimental `-fclangir` flag can now do so with a Clang build. diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index ae6aae4d0d6991..90f6b4fb25a4c3 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -985,6 +985,13 @@ getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind) { using TripleSet = std::multiset<llvm::Triple>; +/// \return the SPIR-V target for SYCL on \p HostTriple: spirv64 on a 64-bit +/// host, spirv32 otherwise. +static llvm::Triple getSYCLDefaultTriple(const llvm::Triple &HostTriple) { + return llvm::Triple(HostTriple.isArch64Bit() ? llvm::Triple::spirv64 + : llvm::Triple::spirv32); +} + // Attempts to infer the correct offloading toolchain triple by looking at the // requested offloading kind and architectures. static TripleSet inferOffloadToolchains(Compilation &C, @@ -1045,6 +1052,11 @@ static TripleSet inferOffloadToolchains(Compilation &C, llvm::Triple Triple = OffloadArchToTriple(C.getDefaultToolChain().getTriple(), ID); + // For SYCL, compile an Intel GPU or CPU, or "generic", for SPIR-V: + // spirv64-unknown-unknown on a 64-bit host, spirv32-unknown-unknown + // otherwise. + if (Kind == Action::OFK_SYCL && (ID.isIntel() || ID.isGeneric())) + Triple = getSYCLDefaultTriple(C.getDefaultToolChain().getTriple()); if (UsesLLVMOffloading) Triple.setEnvironment(llvm::Triple::LLVM); @@ -1077,10 +1089,7 @@ static TripleSet inferOffloadToolchains(Compilation &C, Triples.insert(llvm::Triple(Arch, llvm::Triple::NoSubArch, llvm::Triple::NVIDIA, llvm::Triple::CUDA)); } else if (Archs.empty() && Kind == Action::OFK_SYCL) - Triples.insert( - llvm::Triple(C.getDefaultToolChain().getTriple().isArch64Bit() - ? llvm::Triple::spirv64 - : llvm::Triple::spirv32)); + Triples.insert(getSYCLDefaultTriple(C.getDefaultToolChain().getTriple())); // We need to dispatch these to the appropriate toolchain now. C.getArgs().eraseArg(options::OPT_offload_arch_EQ); diff --git a/clang/test/Driver/sycl-intel-gpu-arch.cpp b/clang/test/Driver/sycl-intel-gpu-arch.cpp index 555391b379ac0e..117488939760c8 100644 --- a/clang/test/Driver/sycl-intel-gpu-arch.cpp +++ b/clang/test/Driver/sycl-intel-gpu-arch.cpp @@ -16,3 +16,41 @@ // CHK-AS-GIVEN-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe-mtl-u)" // CHK-AS-GIVEN-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe-arl-u)" // CHK-AS-GIVEN-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe_12.70.0)" + +/// Without --offload-targets, an Intel device, an IGCA target or "generic" picks +/// SPIR-V of the host's width. +// RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-arch=xe-pvc --offload-arch=xe-bmg-g21 --offload-arch=graniterapids \ +// RUN: --offload-arch=generic --offload-arch=igca_20ca -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-NO-TARGETS %s +// CHK-NO-TARGETS-DAG: offload, "device-sycl (spirv64-unknown-unknown:generic)" +// CHK-NO-TARGETS-DAG: offload, "device-sycl (spirv64-unknown-unknown:graniterapids)" +// CHK-NO-TARGETS-DAG: offload, "device-sycl (spirv64-unknown-unknown:igca_20ca)" +// CHK-NO-TARGETS-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe-bmg-g21)" +// CHK-NO-TARGETS-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe-pvc)" +// RUN: %clang -ccc-print-phases --target=i386-unknown-linux-gnu -fsycl \ +// RUN: --offload-arch=xe-pvc --offload-arch=igca_20ca -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-NO-TARGETS-32 %s +// CHK-NO-TARGETS-32-DAG: offload, "device-sycl (spirv32-unknown-unknown:xe-pvc)" +// CHK-NO-TARGETS-32-DAG: offload, "device-sycl (spirv32-unknown-unknown:igca_20ca)" +// RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-arch=xe-mtl-u --offload-arch=xe-arl-u --offload-arch=xe-pvc \ +// RUN: --no-offload-arch=xe-pvc -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-NO-TARGETS-AS-GIVEN %s +// CHK-NO-TARGETS-AS-GIVEN-NOT: xe-pvc +// CHK-NO-TARGETS-AS-GIVEN-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe-mtl-u)" +// CHK-NO-TARGETS-AS-GIVEN-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe-arl-u)" +// CHK-NO-TARGETS-AS-GIVEN-NOT: xe-pvc + +/// As for CUDA and HIP, -foffload-via-llvm gives the inferred target the LLVM +/// environment. +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fsycl -foffload-via-llvm \ +// RUN: --offload-arch=xe-pvc -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-VIA-LLVM %s +// CHK-VIA-LLVM: "-cc1" "-triple" "spirv64-unknown-unknown-llvm" + +/// Only SYCL infers a target from an Intel name. +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -x cuda -nocudainc \ +// RUN: -nocudalib --offload-arch=xe-pvc -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-CUDA %s +// CHK-CUDA: error: unsupported CUDA gpu architecture: xe-pvc >From 614b4a5d158ee73a2c736fc5e332d09056da5a98 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Fri, 30 Oct 2026 11:45:53 -0700 Subject: [PATCH 2/9] [Clang][SYCL] Skip NVIDIA and AMD GPUs in --offload-arch=native for SYCL SYCL only supports Intel devices, so --offload-arch=native no longer creates SYCL device jobs for the NVIDIA and AMD GPUs that offload-arch reports. --- clang/docs/ReleaseNotes.md | 3 ++- clang/lib/Driver/Driver.cpp | 12 +++++++++--- .../offload_arch_sm_70_gfx906_xe_pvc | 5 +++++ clang/test/Driver/sycl-system-arch.cpp | 16 ++++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) create mode 100755 clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_xe_pvc create mode 100644 clang/test/Driver/sycl-system-arch.cpp diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index ab3762e4473c52..42eb1252597fe7 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -1534,7 +1534,8 @@ The `alpha.cplusplus.UseAfterLifetimeEnd` checker was renamed to `alpha.core.Use - `-fsycl --offload-arch=<arch>` now selects the SPIR-V target without `--offload-targets` when `<arch>` is an Intel GPU (e.g. `xe-pvc`), an IGCA - target (e.g. `igca_20ca`) or `generic`. + target (e.g. `igca_20ca`) or `generic`. `--offload-arch=native` skips NVIDIA + and AMD GPUs, which SYCL does not support. ### Clang IR Improvements diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 90f6b4fb25a4c3..0d8add13291084 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -974,9 +974,15 @@ getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind) { return GPUArchs; } - for (StringRef Arch : llvm::split((*StdoutOrErr)->getBuffer(), "\n")) - if (!Arch.empty()) - GPUArchs.push_back(Arch.str()); + // SYCL only supports Intel devices, so skip NVIDIA and AMD GPUs. + for (StringRef Arch : llvm::split((*StdoutOrErr)->getBuffer(), "\n")) { + OffloadArch ID = StringToOffloadArch(Arch); + if (Arch.empty() || + (Kind == Action::OFK_SYCL && + (ID.isNVPTX() || ID.isAMDGPU() || ID.isAMDGCNSPIRV()))) + continue; + GPUArchs.push_back(Arch.str()); + } } else { C.getDriver().Diag(diag::err_drv_command_failure) << "offload-arch"; } diff --git a/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_xe_pvc b/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_xe_pvc new file mode 100755 index 00000000000000..d6f8f4872fca12 --- /dev/null +++ b/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_xe_pvc @@ -0,0 +1,5 @@ +#!/bin/sh +echo "sm_70" +echo "gfx906" +echo "xe-pvc" +exit 0 diff --git a/clang/test/Driver/sycl-system-arch.cpp b/clang/test/Driver/sycl-system-arch.cpp new file mode 100644 index 00000000000000..b5b7a288a07fb0 --- /dev/null +++ b/clang/test/Driver/sycl-system-arch.cpp @@ -0,0 +1,16 @@ +/// Needs chmod +// UNSUPPORTED: system-windows +// XFAIL: target={{.*}}-zos{{.*}} + +// RUN: mkdir -p %t +// RUN: cp %S/Inputs/offload-arch/offload_arch_sm_70_gfx906_xe_pvc %t/ +// RUN: chmod +x %t/offload_arch_sm_70_gfx906_xe_pvc + +/// SYCL only supports Intel devices, so --offload-arch=native skips NVIDIA and +/// AMD GPUs. +// RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-arch=native --offload-arch-tool=%t/offload_arch_sm_70_gfx906_xe_pvc \ +// RUN: -c %s 2>&1 | FileCheck %s +// CHECK-NOT: {{sm_70|gfx906}} +// CHECK: offload, "device-sycl (spirv64-unknown-unknown:xe-pvc)" +// CHECK-NOT: {{sm_70|gfx906}} >From 559da06118e25cd3cca26ada677f73af43edbcaa Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Fri, 30 Oct 2026 11:47:53 -0700 Subject: [PATCH 3/9] [Clang][SYCL] Reject an unknown offload architecture on a SPIR-V target On a spirv32-unknown-unknown or spirv64-unknown-unknown target, a SYCL --offload-arch or --no-offload-arch value must name an Intel GPU or CPU, an IGCA target or "generic". Diagnose anything else, e.g. a misspelled xe-pcv or xe-pvc:foo, as for CUDA and HIP, instead of building for a device that does not exist. --- clang/docs/ReleaseNotes.md | 5 +++ clang/lib/Driver/Driver.cpp | 32 +++++++++++---- clang/test/Driver/sycl-intel-gpu-arch.cpp | 49 +++++++++++++++++++++++ 3 files changed, 79 insertions(+), 7 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 42eb1252597fe7..7cbd47f2015431 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -1530,6 +1530,11 @@ The `alpha.cplusplus.UseAfterLifetimeEnd` checker was renamed to `alpha.core.Use ### SYCL Support +- On a `spirv32-unknown-unknown` or `spirv64-unknown-unknown` offload target, + `--offload-arch` and `--no-offload-arch` must now name an Intel GPU or CPU, or + `generic`. Any other value, e.g. a misspelled `xe-pcv`, is an error rather + than a device job for a device that does not exist. + #### Improvements - `-fsycl --offload-arch=<arch>` now selects the SPIR-V target without diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 0d8add13291084..3100b7081207a5 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1050,6 +1050,10 @@ static TripleSet inferOffloadToolchains(Compilation &C, << Arch; return {}; } + // An Intel name or "generic" takes no target features. + if (Kind == Action::OFK_SYCL && (ID.isIntel() || ID.isGeneric()) && + Arch.contains(':')) + ID = OffloadArch::getUnknown(); if (ID.isUnknown() || ID.isUnused()) { C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch) << "offload" << Arch; @@ -3938,11 +3942,16 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, - const llvm::Triple &Triple) { - // Lookup the CUDA / HIP architecture string. Only report an error if we were - // expecting the triple to be only NVPTX / AMDGPU. + const llvm::Triple &Triple, + Action::OffloadKind Kind) { + // Look up the architecture. Only report an error if the triple expects an + // NVPTX or AMDGPU one. OffloadArch Arch = StringToOffloadArch(getProcessorFromTargetID(Triple, ArchStr)); + // An Intel name or "generic" takes no target features, so "xe-pvc:foo" is + // not "xe-pvc". + if ((Arch.isIntel() || Arch.isGeneric()) && ArchStr.contains(':')) + Arch = OffloadArch::getUnknown(); if (Triple.isNVPTX() && (Arch.isUnknown() || !Arch.isNVPTX())) { C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch) << "CUDA" << ArchStr; @@ -3969,6 +3978,15 @@ static StringRef getCanonicalArchString(Compilation &C, << "IGCA" << ArchStr; return StringRef(); } + } else if (Kind == Action::OFK_SYCL && Triple.isSPIRV() && + Triple.getVendor() == llvm::Triple::UnknownVendor && + !ArchStr.empty() && !Arch.isIntel() && !Arch.isGeneric()) { + // A SYCL device on a plain SPIR-V target is an Intel GPU or CPU, or + // "generic". Reject anything else, as for CUDA and HIP, rather than build + // for a device that does not exist. + C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch) + << "SYCL" << ArchStr; + return StringRef(); } if (Arch.isNVPTX()) @@ -4032,7 +4050,7 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, for (auto ArchStr : *GPUsOrErr) { StringRef CanonicalStr = getCanonicalArchString( - C, Args, Args.MakeArgString(ArchStr), TC.getTriple()); + C, Args, Args.MakeArgString(ArchStr), TC.getTriple(), Kind); if (!CanonicalStr.empty()) Archs.insert(CanonicalStr); else @@ -4040,7 +4058,7 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, } } else { StringRef CanonicalStr = - getCanonicalArchString(C, Args, Arch, TC.getTriple()); + getCanonicalArchString(C, Args, Arch, TC.getTriple(), Kind); if (!CanonicalStr.empty()) Archs.insert(CanonicalStr); else @@ -4053,7 +4071,7 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Archs.clear(); } else { StringRef ArchStr = - getCanonicalArchString(C, Args, Arch, TC.getTriple()); + getCanonicalArchString(C, Args, Arch, TC.getTriple(), Kind); Archs.erase(ArchStr); } } @@ -4109,7 +4127,7 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, ? "" : OffloadArchToString(TripleOffloadArch); StringRef CanonicalStr = - getCanonicalArchString(C, Args, ArchStr, TC.getTriple()); + getCanonicalArchString(C, Args, ArchStr, TC.getTriple(), Kind); if (!CanonicalStr.empty()) Archs.insert(CanonicalStr); } diff --git a/clang/test/Driver/sycl-intel-gpu-arch.cpp b/clang/test/Driver/sycl-intel-gpu-arch.cpp index 117488939760c8..aac77877ff6475 100644 --- a/clang/test/Driver/sycl-intel-gpu-arch.cpp +++ b/clang/test/Driver/sycl-intel-gpu-arch.cpp @@ -54,3 +54,52 @@ // RUN: -nocudalib --offload-arch=xe-pvc -c %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-CUDA %s // CHK-CUDA: error: unsupported CUDA gpu architecture: xe-pvc + +/// On a SPIR-V target, a SYCL device must be an Intel GPU or CPU, or "generic". +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-unknown-unknown --offload-arch=xe-pcv -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-BAD-ARCH %s +// CHK-BAD-ARCH: error: unsupported SYCL gpu architecture: xe-pcv +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-unknown-unknown --offload-arch=bmg_g21 -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-BAD-ARCH-OLD %s +// CHK-BAD-ARCH-OLD: error: unsupported SYCL gpu architecture: bmg_g21 +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-unknown-unknown --offload-arch=xe_12.60. -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-BAD-ARCH-NUM %s +// CHK-BAD-ARCH-NUM: error: unsupported SYCL gpu architecture: xe_12.60. +/// A numeric name names no device unless the list has its GPU IP version. +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-unknown-unknown --offload-arch=xe_40.11.0 -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-BAD-ARCH-UNLISTED %s +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-arch=xe_40.11.0 -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-BAD-ARCH-UNLISTED %s +// CHK-BAD-ARCH-UNLISTED: error: unsupported {{SYCL|offload}} gpu architecture: xe_40.11.0 +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-unknown-unknown --offload-arch=xe-pvc:garbage -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-BAD-ARCH-SUFFIX %s +// CHK-BAD-ARCH-SUFFIX: error: unsupported SYCL gpu architecture: xe-pvc:garbage +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-unknown-unknown --offload-arch=generic:foo -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-BAD-GENERIC %s +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-arch=generic:foo -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-BAD-GENERIC %s +// CHK-BAD-GENERIC: error: unsupported {{SYCL|offload}} gpu architecture: generic:foo +/// As for CUDA and HIP, --no-offload-arch is checked too when the target is +/// given. +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-unknown-unknown --offload-arch=xe-pvc \ +// RUN: --no-offload-arch=foo -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-BAD-NO-ARCH %s +// CHK-BAD-NO-ARCH: error: unsupported SYCL gpu architecture: foo +/// Only a plain SPIR-V target is checked. +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-intel --offload-arch=foo -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-NOT-CHECKED %s +// CHK-NOT-CHECKED-NOT: error: +// RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-unknown-unknown --offload-arch=graniterapids \ +// RUN: -c %s 2>&1 | FileCheck -check-prefixes=CHK-GOOD-ARCH %s +// CHK-GOOD-ARCH: offload, "device-sycl (spirv64-unknown-unknown:graniterapids)" >From 370a96527bd9609b6098a7e26a4e053e301c0ee0 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Fri, 30 Oct 2026 11:48:19 -0700 Subject: [PATCH 4/9] [Clang][SYCL] Require a plain SPIR-V target for an Intel offload architecture Intel GPU and CPU names and IGCA targets always use a plain SPIR-V target such as spirv64-unknown-unknown, so diagnose them on any other SPIR-V target, e.g. spirv64-amd-amdhsa. A valid IGCA target now reaches this check too. --- clang/lib/Driver/Driver.cpp | 21 ++++++++++++++------ clang/test/Driver/sycl-intel-gpu-arch.cpp | 14 +++++++++++++ clang/test/Driver/sycl-offload-arch-igca.cpp | 10 ++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 3100b7081207a5..d59c3bdd473e43 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3972,12 +3972,13 @@ static StringRef getCanonicalArchString(Compilation &C, return StringRef(); } } - } else if (Triple.isSPIRV() && ArchStr.starts_with("igca")) { - if (!StringToOffloadArch(ArchStr).isIntelIGCA()) { - C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch) - << "IGCA" << ArchStr; - return StringRef(); - } + } else if (Triple.isSPIRV() && ArchStr.starts_with("igca") && + !StringToOffloadArch(ArchStr).isIntelIGCA()) { + // Only an invalid IGCA target stops here; a valid one still needs the + // SPIR-V target checks below. + C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch) + << "IGCA" << ArchStr; + return StringRef(); } else if (Kind == Action::OFK_SYCL && Triple.isSPIRV() && Triple.getVendor() == llvm::Triple::UnknownVendor && !ArchStr.empty() && !Arch.isIntel() && !Arch.isGeneric()) { @@ -3987,6 +3988,14 @@ static StringRef getCanonicalArchString(Compilation &C, C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch) << "SYCL" << ArchStr; return StringRef(); + } else if (Kind == Action::OFK_SYCL && Triple.isSPIRV() && Arch.isIntel() && + (Triple.getVendor() != llvm::Triple::UnknownVendor || + Triple.getOS() != llvm::Triple::UnknownOS)) { + // Intel names always use a plain SPIR-V target such as + // spirv64-unknown-unknown, so reject them on any other SPIR-V target. + C.getDriver().Diag(clang::diag::err_target_unsupported_arch) + << ArchStr << Triple.str(); + return StringRef(); } if (Arch.isNVPTX()) diff --git a/clang/test/Driver/sycl-intel-gpu-arch.cpp b/clang/test/Driver/sycl-intel-gpu-arch.cpp index aac77877ff6475..b5f042aae89306 100644 --- a/clang/test/Driver/sycl-intel-gpu-arch.cpp +++ b/clang/test/Driver/sycl-intel-gpu-arch.cpp @@ -99,6 +99,20 @@ // RUN: --offload-targets=spirv64-intel --offload-arch=foo -c %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-NOT-CHECKED %s // CHK-NOT-CHECKED-NOT: error: +/// An Intel name needs a plain SPIR-V target. +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-intel --offload-arch=xe-pvc -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-NOT-PLAIN -DARCH=xe-pvc -DTRIPLE=spirv64-intel %s +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-amd-amdhsa --offload-arch=xe-pvc -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-NOT-PLAIN -DARCH=xe-pvc -DTRIPLE=spirv64-amd-amdhsa %s +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-unknown-amdhsa --offload-arch=xe-pvc -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-NOT-PLAIN -DARCH=xe-pvc -DTRIPLE=spirv64-unknown-amdhsa %s +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-intel --offload-arch=graniterapids -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-NOT-PLAIN -DARCH=graniterapids -DTRIPLE=spirv64-intel %s +// CHK-NOT-PLAIN: error: the target architecture '[[ARCH]]' is not supported by the target '[[TRIPLE]]' // RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \ // RUN: --offload-targets=spirv64-unknown-unknown --offload-arch=graniterapids \ // RUN: -c %s 2>&1 | FileCheck -check-prefixes=CHK-GOOD-ARCH %s diff --git a/clang/test/Driver/sycl-offload-arch-igca.cpp b/clang/test/Driver/sycl-offload-arch-igca.cpp index 7a3a2b4f7d7ace..1b948af1bb9d57 100644 --- a/clang/test/Driver/sycl-offload-arch-igca.cpp +++ b/clang/test/Driver/sycl-offload-arch-igca.cpp @@ -33,3 +33,13 @@ // RUN: -c %s 2>&1 | FileCheck -check-prefix=CHK-AMDGPU %s // CHK-AMDGPU: error: unsupported HIP gpu architecture: igca_20ca // CHK-AMDGPU-NOT: llvm-offload-binary + +/// A valid IGCA target, like an Intel GPU name, needs a plain SPIR-V target: +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-amd-amdhsa --offload-arch=igca_20ca \ +// RUN: -c %s 2>&1 | FileCheck -check-prefix=CHK-NOT-PLAIN -DTRIPLE=spirv64-amd-amdhsa %s +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-unknown-amdhsa --offload-arch=igca_20ca \ +// RUN: -c %s 2>&1 | FileCheck -check-prefix=CHK-NOT-PLAIN -DTRIPLE=spirv64-unknown-amdhsa %s +// CHK-NOT-PLAIN: error: the target architecture 'igca_20ca' is not supported by the target '[[TRIPLE]]' +// CHK-NOT-PLAIN-NOT: llvm-offload-binary >From 250d95d7a20240d45940f3dc1805999ed6ec73b7 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Fri, 30 Oct 2026 12:32:12 -0700 Subject: [PATCH 5/9] [Clang][SYCL] Skip an AMD GPU with target features in --offload-arch=native offload-arch can report an AMD GPU with its target features, e.g. gfx90a:sramecc+:xnack-, which StringToOffloadArch does not recognize, so SYCL built a device job for it. Strip the target features of an unrecognized name before checking for an AMD GPU, as inferOffloadToolchains does. --- clang/lib/Driver/Driver.cpp | 7 ++++++- ...e_pvc => offload_arch_sm_70_gfx906_gfx90a_xe_pvc} | 1 + clang/test/Driver/sycl-system-arch.cpp | 12 ++++++------ 3 files changed, 13 insertions(+), 7 deletions(-) rename clang/test/Driver/Inputs/offload-arch/{offload_arch_sm_70_gfx906_xe_pvc => offload_arch_sm_70_gfx906_gfx90a_xe_pvc} (65%) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 0d8add13291084..3f741f984e23cc 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -974,9 +974,14 @@ getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind) { return GPUArchs; } - // SYCL only supports Intel devices, so skip NVIDIA and AMD GPUs. + // SYCL only supports Intel devices, so skip NVIDIA and AMD GPUs. An AMD GPU + // may come with target features, e.g. "gfx90a:sramecc+:xnack-". + llvm::Triple AMDGPUTriple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch, + llvm::Triple::AMD, llvm::Triple::AMDHSA); for (StringRef Arch : llvm::split((*StdoutOrErr)->getBuffer(), "\n")) { OffloadArch ID = StringToOffloadArch(Arch); + if (ID.isUnknown()) + ID = StringToOffloadArch(getProcessorFromTargetID(AMDGPUTriple, Arch)); if (Arch.empty() || (Kind == Action::OFK_SYCL && (ID.isNVPTX() || ID.isAMDGPU() || ID.isAMDGCNSPIRV()))) diff --git a/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_xe_pvc b/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_gfx90a_xe_pvc similarity index 65% rename from clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_xe_pvc rename to clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_gfx90a_xe_pvc index d6f8f4872fca12..7f852bfbd1c134 100755 --- a/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_xe_pvc +++ b/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_gfx90a_xe_pvc @@ -1,5 +1,6 @@ #!/bin/sh echo "sm_70" echo "gfx906" +echo "gfx90a:sramecc+:xnack-" echo "xe-pvc" exit 0 diff --git a/clang/test/Driver/sycl-system-arch.cpp b/clang/test/Driver/sycl-system-arch.cpp index b5b7a288a07fb0..450b564b0ea4c4 100644 --- a/clang/test/Driver/sycl-system-arch.cpp +++ b/clang/test/Driver/sycl-system-arch.cpp @@ -3,14 +3,14 @@ // XFAIL: target={{.*}}-zos{{.*}} // RUN: mkdir -p %t -// RUN: cp %S/Inputs/offload-arch/offload_arch_sm_70_gfx906_xe_pvc %t/ -// RUN: chmod +x %t/offload_arch_sm_70_gfx906_xe_pvc +// RUN: cp %S/Inputs/offload-arch/offload_arch_sm_70_gfx906_gfx90a_xe_pvc %t/ +// RUN: chmod +x %t/offload_arch_sm_70_gfx906_gfx90a_xe_pvc /// SYCL only supports Intel devices, so --offload-arch=native skips NVIDIA and -/// AMD GPUs. +/// AMD GPUs, including an AMD GPU with target features. // RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \ -// RUN: --offload-arch=native --offload-arch-tool=%t/offload_arch_sm_70_gfx906_xe_pvc \ +// RUN: --offload-arch=native --offload-arch-tool=%t/offload_arch_sm_70_gfx906_gfx90a_xe_pvc \ // RUN: -c %s 2>&1 | FileCheck %s -// CHECK-NOT: {{sm_70|gfx906}} +// CHECK-NOT: {{sm_70|gfx9}} // CHECK: offload, "device-sycl (spirv64-unknown-unknown:xe-pvc)" -// CHECK-NOT: {{sm_70|gfx906}} +// CHECK-NOT: {{sm_70|gfx9}} >From 4a81882dda13bb27fc52a08d4ac8a5020c6186c7 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Fri, 30 Oct 2026 15:19:42 -0700 Subject: [PATCH 6/9] [Clang][SYCL] Drop the release note, test an inferred numeric Intel GPU name Leave the release note for when --offload-arch for SYCL is complete, as for the Intel GPU names. Test that a numeric name such as xe_12.60.7 also selects the SPIR-V target without --offload-targets. --- clang/docs/ReleaseNotes.md | 5 ----- clang/test/Driver/sycl-intel-gpu-arch.cpp | 9 +++++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 42eb1252597fe7..4b9e9228380d1d 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -1532,11 +1532,6 @@ The `alpha.cplusplus.UseAfterLifetimeEnd` checker was renamed to `alpha.core.Use #### Improvements -- `-fsycl --offload-arch=<arch>` now selects the SPIR-V target without - `--offload-targets` when `<arch>` is an Intel GPU (e.g. `xe-pvc`), an IGCA - target (e.g. `igca_20ca`) or `generic`. `--offload-arch=native` skips NVIDIA - and AMD GPUs, which SYCL does not support. - ### Clang IR Improvements - Clang builds now build ClangIR support by default. Clang IR is expected to work with most Linux/X86-64 workloads. Normal builds are unchanged, however those who wish to test out the experimental `-fclangir` flag can now do so with a Clang build. diff --git a/clang/test/Driver/sycl-intel-gpu-arch.cpp b/clang/test/Driver/sycl-intel-gpu-arch.cpp index 117488939760c8..6022155645a174 100644 --- a/clang/test/Driver/sycl-intel-gpu-arch.cpp +++ b/clang/test/Driver/sycl-intel-gpu-arch.cpp @@ -17,17 +17,18 @@ // CHK-AS-GIVEN-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe-arl-u)" // CHK-AS-GIVEN-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe_12.70.0)" -/// Without --offload-targets, an Intel device, an IGCA target or "generic" picks -/// SPIR-V of the host's width. +/// Without --offload-targets, an Intel device (by name or numeric name), an IGCA +/// target or "generic" picks SPIR-V of the host's width. // RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \ // RUN: --offload-arch=xe-pvc --offload-arch=xe-bmg-g21 --offload-arch=graniterapids \ -// RUN: --offload-arch=generic --offload-arch=igca_20ca -c %s 2>&1 \ -// RUN: | FileCheck -check-prefixes=CHK-NO-TARGETS %s +// RUN: --offload-arch=generic --offload-arch=igca_20ca --offload-arch=xe_12.60.7 \ +// RUN: -c %s 2>&1 | FileCheck -check-prefixes=CHK-NO-TARGETS %s // CHK-NO-TARGETS-DAG: offload, "device-sycl (spirv64-unknown-unknown:generic)" // CHK-NO-TARGETS-DAG: offload, "device-sycl (spirv64-unknown-unknown:graniterapids)" // CHK-NO-TARGETS-DAG: offload, "device-sycl (spirv64-unknown-unknown:igca_20ca)" // CHK-NO-TARGETS-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe-bmg-g21)" // CHK-NO-TARGETS-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe-pvc)" +// CHK-NO-TARGETS-DAG: offload, "device-sycl (spirv64-unknown-unknown:xe_12.60.7)" // RUN: %clang -ccc-print-phases --target=i386-unknown-linux-gnu -fsycl \ // RUN: --offload-arch=xe-pvc --offload-arch=igca_20ca -c %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-NO-TARGETS-32 %s >From a104105befabcd3a6e7f97cc12e637777f576a04 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Fri, 30 Oct 2026 15:53:29 -0700 Subject: [PATCH 7/9] [Clang][SYCL] Address review: share target-feature handling, tighten tests Add getOffloadArchIgnoringFeatures for the AMD target-feature fallback used by both --offload-arch=native and target inference, and classify native GPUs only for SYCL. Mention IGCA targets in the inference comment, check for AMD and NVIDIA device jobs directly in the native test, and explain the alias test. --- clang/lib/Driver/Driver.cpp | 39 ++++++++++++----------- clang/test/Driver/sycl-intel-gpu-arch.cpp | 2 ++ clang/test/Driver/sycl-system-arch.cpp | 6 ++-- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 3f741f984e23cc..0abe7092e43784 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -940,6 +940,17 @@ Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const { return RT; } +/// \return the OffloadArch \p Arch names. An AMD GPU may come with target +/// features, which are ignored, e.g. "gfx90a:sramecc+:xnack-" is gfx90a. +static OffloadArch getOffloadArchIgnoringFeatures(StringRef Arch) { + OffloadArch ID = StringToOffloadArch(Arch); + if (!ID.isUnknown()) + return ID; + llvm::Triple AMDGPUTriple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch, + llvm::Triple::AMD, llvm::Triple::AMDHSA); + return StringToOffloadArch(getProcessorFromTargetID(AMDGPUTriple, Arch)); +} + // Handles `native` offload architectures by using the 'offload-arch' utility. static llvm::SmallVector<std::string> getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind) { @@ -974,18 +985,15 @@ getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind) { return GPUArchs; } - // SYCL only supports Intel devices, so skip NVIDIA and AMD GPUs. An AMD GPU - // may come with target features, e.g. "gfx90a:sramecc+:xnack-". - llvm::Triple AMDGPUTriple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch, - llvm::Triple::AMD, llvm::Triple::AMDHSA); for (StringRef Arch : llvm::split((*StdoutOrErr)->getBuffer(), "\n")) { - OffloadArch ID = StringToOffloadArch(Arch); - if (ID.isUnknown()) - ID = StringToOffloadArch(getProcessorFromTargetID(AMDGPUTriple, Arch)); - if (Arch.empty() || - (Kind == Action::OFK_SYCL && - (ID.isNVPTX() || ID.isAMDGPU() || ID.isAMDGCNSPIRV()))) + if (Arch.empty()) continue; + // SYCL only supports Intel devices, so skip NVIDIA and AMD GPUs. + if (Kind == Action::OFK_SYCL) { + OffloadArch ID = getOffloadArchIgnoringFeatures(Arch); + if (ID.isNVPTX() || ID.isAMDGPU() || ID.isAMDGCNSPIRV()) + continue; + } GPUArchs.push_back(Arch.str()); } } else { @@ -1028,12 +1036,7 @@ static TripleSet inferOffloadToolchains(Compilation &C, TripleSet Triples; for (llvm::StringRef Arch : Archs) { - OffloadArch ID = StringToOffloadArch(Arch); - if (ID.isUnknown()) { - llvm::Triple AMDGPUTriple(llvm::Triple::amdgpu, llvm::Triple::NoSubArch, - llvm::Triple::AMD, llvm::Triple::AMDHSA); - ID = StringToOffloadArch(getProcessorFromTargetID(AMDGPUTriple, Arch)); - } + OffloadArch ID = getOffloadArchIgnoringFeatures(Arch); bool UsesLLVMOffloading = C.getArgs().hasFlag(options::OPT_foffload_via_llvm, @@ -1063,8 +1066,8 @@ static TripleSet inferOffloadToolchains(Compilation &C, llvm::Triple Triple = OffloadArchToTriple(C.getDefaultToolChain().getTriple(), ID); - // For SYCL, compile an Intel GPU or CPU, or "generic", for SPIR-V: - // spirv64-unknown-unknown on a 64-bit host, spirv32-unknown-unknown + // For SYCL, compile an Intel GPU or CPU, an IGCA target or "generic" for + // SPIR-V: spirv64-unknown-unknown on a 64-bit host, spirv32-unknown-unknown // otherwise. if (Kind == Action::OFK_SYCL && (ID.isIntel() || ID.isGeneric())) Triple = getSYCLDefaultTriple(C.getDefaultToolChain().getTriple()); diff --git a/clang/test/Driver/sycl-intel-gpu-arch.cpp b/clang/test/Driver/sycl-intel-gpu-arch.cpp index 6022155645a174..e0169b95b84ee3 100644 --- a/clang/test/Driver/sycl-intel-gpu-arch.cpp +++ b/clang/test/Driver/sycl-intel-gpu-arch.cpp @@ -34,6 +34,8 @@ // RUN: | FileCheck -check-prefixes=CHK-NO-TARGETS-32 %s // CHK-NO-TARGETS-32-DAG: offload, "device-sycl (spirv32-unknown-unknown:xe-pvc)" // CHK-NO-TARGETS-32-DAG: offload, "device-sycl (spirv32-unknown-unknown:igca_20ca)" +/// Names are kept as given, so two aliases of one device make two device jobs, +/// and --no-offload-arch removes a name. // RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \ // RUN: --offload-arch=xe-mtl-u --offload-arch=xe-arl-u --offload-arch=xe-pvc \ // RUN: --no-offload-arch=xe-pvc -c %s 2>&1 \ diff --git a/clang/test/Driver/sycl-system-arch.cpp b/clang/test/Driver/sycl-system-arch.cpp index 450b564b0ea4c4..76cccdcc7a8ae1 100644 --- a/clang/test/Driver/sycl-system-arch.cpp +++ b/clang/test/Driver/sycl-system-arch.cpp @@ -1,4 +1,4 @@ -/// Needs chmod +// Needs chmod // UNSUPPORTED: system-windows // XFAIL: target={{.*}}-zos{{.*}} @@ -11,6 +11,6 @@ // RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \ // RUN: --offload-arch=native --offload-arch-tool=%t/offload_arch_sm_70_gfx906_gfx90a_xe_pvc \ // RUN: -c %s 2>&1 | FileCheck %s -// CHECK-NOT: {{sm_70|gfx9}} +// CHECK-NOT: "device-sycl ({{amdgpu|nvptx}} // CHECK: offload, "device-sycl (spirv64-unknown-unknown:xe-pvc)" -// CHECK-NOT: {{sm_70|gfx9}} +// CHECK-NOT: "device-sycl ({{amdgpu|nvptx}} >From 9256900f5462d929e05709c06b3f57656c9868ab Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Fri, 30 Oct 2026 16:41:59 -0700 Subject: [PATCH 8/9] [Clang][SYCL] Address review: reword the native GPU skip comments --- clang/lib/Driver/Driver.cpp | 3 ++- clang/test/Driver/sycl-system-arch.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 0abe7092e43784..529037937373ed 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -988,7 +988,8 @@ getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind) { for (StringRef Arch : llvm::split((*StdoutOrErr)->getBuffer(), "\n")) { if (Arch.empty()) continue; - // SYCL only supports Intel devices, so skip NVIDIA and AMD GPUs. + // Skip NVIDIA and AMD GPUs, since clang does not support SYCL offloading + // to them. if (Kind == Action::OFK_SYCL) { OffloadArch ID = getOffloadArchIgnoringFeatures(Arch); if (ID.isNVPTX() || ID.isAMDGPU() || ID.isAMDGCNSPIRV()) diff --git a/clang/test/Driver/sycl-system-arch.cpp b/clang/test/Driver/sycl-system-arch.cpp index 76cccdcc7a8ae1..7488bdff74d415 100644 --- a/clang/test/Driver/sycl-system-arch.cpp +++ b/clang/test/Driver/sycl-system-arch.cpp @@ -6,8 +6,8 @@ // RUN: cp %S/Inputs/offload-arch/offload_arch_sm_70_gfx906_gfx90a_xe_pvc %t/ // RUN: chmod +x %t/offload_arch_sm_70_gfx906_gfx90a_xe_pvc -/// SYCL only supports Intel devices, so --offload-arch=native skips NVIDIA and -/// AMD GPUs, including an AMD GPU with target features. +/// For SYCL offloading, --offload-arch=native skips NVIDIA and AMD GPUs, +/// including an AMD GPU with target features. // RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \ // RUN: --offload-arch=native --offload-arch-tool=%t/offload_arch_sm_70_gfx906_gfx90a_xe_pvc \ // RUN: -c %s 2>&1 | FileCheck %s >From 1811d7af6a8cc706aff21ce304b676823c29e742 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Fri, 30 Oct 2026 16:56:34 -0700 Subject: [PATCH 9/9] [Clang][SYCL] Address review: one definition of a plain SPIR-V target Add isPlainSPIRV and use it for both SYCL checks, so a target with an OS such as spirv64-unknown-amdhsa is no longer plain for one check but not the other. Mention IGCA targets in the release note and comments, and update the comments of getCanonicalArchString. --- clang/docs/ReleaseNotes.md | 6 ++--- clang/lib/Driver/Driver.cpp | 33 +++++++++++++---------- clang/test/Driver/sycl-intel-gpu-arch.cpp | 6 ++++- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 85620a9b5221fe..2fcdb4ca2296f5 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -1531,9 +1531,9 @@ The `alpha.cplusplus.UseAfterLifetimeEnd` checker was renamed to `alpha.core.Use ### SYCL Support - On a `spirv32-unknown-unknown` or `spirv64-unknown-unknown` offload target, - `--offload-arch` and `--no-offload-arch` must now name an Intel GPU or CPU, or - `generic`. Any other value, e.g. a misspelled `xe-pcv`, is an error rather - than a device job for a device that does not exist. + `--offload-arch` and `--no-offload-arch` must now name an Intel GPU or CPU, an + IGCA target or `generic`. Any other value, e.g. a misspelled `xe-pcv`, is an + error rather than a device job for a device that does not exist. #### Improvements diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 21e377b4ce5e5b..e20c9887d0f2af 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3946,15 +3946,22 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, Args.ClaimAllArgs(options::OPT_cl_ignored_Group); } -/// Returns the canonical name for the offloading architecture when using a HIP -/// or CUDA architecture. +/// \return true if \p Triple is a SPIR-V target with no vendor or OS, such as +/// spirv64-unknown-unknown. +static bool isPlainSPIRV(const llvm::Triple &Triple) { + return Triple.isSPIRV() && + Triple.getVendor() == llvm::Triple::UnknownVendor && + Triple.getOS() == llvm::Triple::UnknownOS; +} + +/// Returns the canonical name for the offloading architecture \p ArchStr on +/// \p Triple, or an empty string after diagnosing an architecture that +/// \p Triple does not support. static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple, Action::OffloadKind Kind) { - // Look up the architecture. Only report an error if the triple expects an - // NVPTX or AMDGPU one. OffloadArch Arch = StringToOffloadArch(getProcessorFromTargetID(Triple, ArchStr)); // An Intel name or "generic" takes no target features, so "xe-pvc:foo" is @@ -3988,20 +3995,18 @@ static StringRef getCanonicalArchString(Compilation &C, C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch) << "IGCA" << ArchStr; return StringRef(); - } else if (Kind == Action::OFK_SYCL && Triple.isSPIRV() && - Triple.getVendor() == llvm::Triple::UnknownVendor && + } else if (Kind == Action::OFK_SYCL && isPlainSPIRV(Triple) && !ArchStr.empty() && !Arch.isIntel() && !Arch.isGeneric()) { - // A SYCL device on a plain SPIR-V target is an Intel GPU or CPU, or - // "generic". Reject anything else, as for CUDA and HIP, rather than build - // for a device that does not exist. + // A SYCL device on a plain SPIR-V target is an Intel GPU or CPU, an IGCA + // target or "generic". Reject anything else, as for CUDA and HIP, rather + // than build for a device that does not exist. C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch) << "SYCL" << ArchStr; return StringRef(); - } else if (Kind == Action::OFK_SYCL && Triple.isSPIRV() && Arch.isIntel() && - (Triple.getVendor() != llvm::Triple::UnknownVendor || - Triple.getOS() != llvm::Triple::UnknownOS)) { - // Intel names always use a plain SPIR-V target such as - // spirv64-unknown-unknown, so reject them on any other SPIR-V target. + } else if (Kind == Action::OFK_SYCL && Triple.isSPIRV() && + !isPlainSPIRV(Triple) && Arch.isIntel()) { + // An Intel name or IGCA target always uses a plain SPIR-V target, so + // reject it on any other SPIR-V target. C.getDriver().Diag(clang::diag::err_target_unsupported_arch) << ArchStr << Triple.str(); return StringRef(); diff --git a/clang/test/Driver/sycl-intel-gpu-arch.cpp b/clang/test/Driver/sycl-intel-gpu-arch.cpp index bc5905e2ac80a3..db3f451ddd1b66 100644 --- a/clang/test/Driver/sycl-intel-gpu-arch.cpp +++ b/clang/test/Driver/sycl-intel-gpu-arch.cpp @@ -58,7 +58,8 @@ // RUN: | FileCheck -check-prefixes=CHK-CUDA %s // CHK-CUDA: error: unsupported CUDA gpu architecture: xe-pvc -/// On a SPIR-V target, a SYCL device must be an Intel GPU or CPU, or "generic". +/// On a plain SPIR-V target, a SYCL device must be an Intel GPU or CPU, an IGCA +/// target or "generic". // RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ // RUN: --offload-targets=spirv64-unknown-unknown --offload-arch=xe-pcv -c %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-BAD-ARCH %s @@ -101,6 +102,9 @@ // RUN: %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ // RUN: --offload-targets=spirv64-intel --offload-arch=foo -c %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-NOT-CHECKED %s +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-targets=spirv64-unknown-amdhsa --offload-arch=foo -c %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-NOT-CHECKED %s // CHK-NOT-CHECKED-NOT: error: /// An Intel name needs a plain SPIR-V target. // RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
