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

Reply via email to