https://github.com/srividya-sundaram updated https://github.com/llvm/llvm-project/pull/229248
>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/7] [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/7] [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 250d95d7a20240d45940f3dc1805999ed6ec73b7 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Fri, 30 Oct 2026 12:32:12 -0700 Subject: [PATCH 3/7] [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 4/7] [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 5/7] [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 6/7] [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 10058bde3bada87efc799fad81fbff8d7de5ada9 Mon Sep 17 00:00:00 2001 From: srividya sundaram <[email protected]> Date: Mon, 2 Nov 2026 10:54:20 -0800 Subject: [PATCH 7/7] [Clang][SYCL] Address review: use offload-arch --only=intel for SYCL As for HIP and CUDA, ask offload-arch for the vendor's GPUs only instead of filtering its output, which removes the NVIDIA and AMD filter and its target-feature handling. Without an Intel GPU, SYCL now reports that no GPU was found, as HIP and CUDA do. --- clang/lib/Driver/Driver.cpp | 35 ++++++------------- .../offload_arch_sm_70_gfx906_gfx90a_xe_pvc | 5 +++ .../offload-arch/offload_arch_sm_70_gfx90a | 8 +++++ clang/test/Driver/sycl-system-arch.cpp | 13 +++++-- 4 files changed, 35 insertions(+), 26 deletions(-) create mode 100755 clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx90a diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 529037937373ed..ee59b3bb42b4e3 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -940,17 +940,6 @@ 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) { @@ -969,6 +958,8 @@ getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind) { Args.push_back("--only=amdgpu"); else if (Kind == Action::OFK_Cuda) Args.push_back("--only=nvptx"); + else if (Kind == Action::OFK_SYCL) + Args.push_back("--only=intel"); } auto StdoutOrErr = C.getDriver().executeProgram(Args); @@ -985,18 +976,9 @@ getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind) { return GPUArchs; } - for (StringRef Arch : llvm::split((*StdoutOrErr)->getBuffer(), "\n")) { - if (Arch.empty()) - continue; - // 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()) - continue; - } - GPUArchs.push_back(Arch.str()); - } + for (StringRef Arch : llvm::split((*StdoutOrErr)->getBuffer(), "\n")) + if (!Arch.empty()) + GPUArchs.push_back(Arch.str()); } else { C.getDriver().Diag(diag::err_drv_command_failure) << "offload-arch"; } @@ -1037,7 +1019,12 @@ static TripleSet inferOffloadToolchains(Compilation &C, TripleSet Triples; for (llvm::StringRef Arch : Archs) { - OffloadArch ID = getOffloadArchIgnoringFeatures(Arch); + 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)); + } bool UsesLLVMOffloading = C.getArgs().hasFlag(options::OPT_foffload_via_llvm, diff --git a/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_gfx90a_xe_pvc b/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_gfx90a_xe_pvc index 7f852bfbd1c134..c9ae7fdda1cf89 100755 --- a/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_gfx90a_xe_pvc +++ b/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx906_gfx90a_xe_pvc @@ -1,4 +1,9 @@ #!/bin/sh +# Like offload-arch, print only the Intel GPU for --only=intel. +if [ "$1" = "--only=intel" ]; then + echo "xe-pvc" + exit 0 +fi echo "sm_70" echo "gfx906" echo "gfx90a:sramecc+:xnack-" diff --git a/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx90a b/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx90a new file mode 100755 index 00000000000000..b654674de614d3 --- /dev/null +++ b/clang/test/Driver/Inputs/offload-arch/offload_arch_sm_70_gfx90a @@ -0,0 +1,8 @@ +#!/bin/sh +# Like offload-arch, print nothing for --only=intel, as there is no Intel GPU. +if [ "$1" = "--only=intel" ]; then + exit 0 +fi +echo "sm_70" +echo "gfx90a:sramecc+:xnack-" +exit 0 diff --git a/clang/test/Driver/sycl-system-arch.cpp b/clang/test/Driver/sycl-system-arch.cpp index 7488bdff74d415..b5c86ab760f04f 100644 --- a/clang/test/Driver/sycl-system-arch.cpp +++ b/clang/test/Driver/sycl-system-arch.cpp @@ -4,13 +4,22 @@ // RUN: mkdir -p %t // RUN: cp %S/Inputs/offload-arch/offload_arch_sm_70_gfx906_gfx90a_xe_pvc %t/ +// RUN: cp %S/Inputs/offload-arch/offload_arch_sm_70_gfx90a %t/ // RUN: chmod +x %t/offload_arch_sm_70_gfx906_gfx90a_xe_pvc +// RUN: chmod +x %t/offload_arch_sm_70_gfx90a -/// For SYCL offloading, --offload-arch=native skips NVIDIA and AMD GPUs, -/// including an AMD GPU with target features. +/// For SYCL offloading, --offload-arch=native asks offload-arch for Intel GPUs +/// only. // 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: "device-sycl ({{amdgpu|nvptx}} // CHECK: offload, "device-sycl (spirv64-unknown-unknown:xe-pvc)" // CHECK-NOT: "device-sycl ({{amdgpu|nvptx}} + +/// Without an Intel GPU, SYCL reports that no GPU was found, as HIP and CUDA +/// do. +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fsycl \ +// RUN: --offload-arch=native --offload-arch-tool=%t/offload_arch_sm_70_gfx90a \ +// RUN: -c %s 2>&1 | FileCheck -check-prefix=NO-GPU %s +// NO-GPU: error: cannot determine sycl architecture: No GPU detected in the system _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
