https://github.com/schittir updated 
https://github.com/llvm/llvm-project/pull/208196

>From b0e5f9aa828119c5fa5017ca959fdc2bc401ef81 Mon Sep 17 00:00:00 2001
From: Sindhu Chittireddy <[email protected]>
Date: Mon, 6 Jul 2026 11:57:38 -0700
Subject: [PATCH 1/4] [SYCL][SPIR-V] Implement fix for Windows/MSVC SPIR-V
 device target support

The following are five gaps identified ing the existing host-adaptation
mechanism in BaseSPIRTargetInfo, causing incorrect behaviour on Windows.

  1. SizeType/PtrDiffType/IntPtrType: not copied from host; hardcoded to
     LP64 defaults in derived classes, giving 32-bit size_t on Win64.
  2. UseMicrosoftManglingForC: never inherited; operator new mangles as
     _Znwm (unsigned long) instead of _Znwy (unsigned long long).
  3. getBuiltinVaListKind(): returns VoidPtr unconditionally instead of
     delegating to the host's va_list kind.
  4. checkCallingConvention(): rejects host calling conventions
     (__vectorcall, __regcall) that device code inherits from shared
     headers.
  5. Derived-class defaults: unconditionally overwrite host-adapted
     values, working on Linux only by coincidence.

This patch extends BaseSPIRTargetInfo's host-adaptation mechanism to
attempt fixing existing issues for Windows support, by copying pointer-related
types from the host, querying for the right mangling, delegating va_list and
calling convention checks to the host, and guarding derived-class fallbacks
behind if(!HostTarget).

This patch also introduces SPIRVPhysicalTargetInfo as a unified base for
spirv32/spirv64 that derives pointer width from the host target when available.

Overall, this patch takes advantage of the existing OS-agnostic aux-triple
mechanism currently used for Linux, to work for Windows without introducing
new triples.
---
 clang/lib/Basic/Targets/SPIR.h                | 99 ++++++++++++-------
 .../spirv-host-adaptation-mangling.cpp        | 16 +++
 .../CodeGenSYCL/spirv-host-adaptation-new.cpp | 23 +++++
 .../spir-target-host-adaptation.cpp           | 33 +++++++
 .../spirv-host-adaptation-valist.cpp          | 12 +++
 .../spirv-target-host-adaptation.cpp          | 70 +++++++++++++
 .../test/SemaSYCL/sycl-spirv-cconv-nohost.cpp |  8 ++
 clang/test/SemaSYCL/sycl-spirv-cconv-win.cpp  | 18 ++++
 .../SemaSYCL/sycl-spirv-host-adaptation.cpp   | 18 ++++
 9 files changed, 261 insertions(+), 36 deletions(-)
 create mode 100644 clang/test/CodeGenSYCL/spirv-host-adaptation-mangling.cpp
 create mode 100644 clang/test/CodeGenSYCL/spirv-host-adaptation-new.cpp
 create mode 100644 clang/test/Preprocessor/spir-target-host-adaptation.cpp
 create mode 100644 clang/test/Preprocessor/spirv-host-adaptation-valist.cpp
 create mode 100644 clang/test/Preprocessor/spirv-target-host-adaptation.cpp
 create mode 100644 clang/test/SemaSYCL/sycl-spirv-cconv-nohost.cpp
 create mode 100644 clang/test/SemaSYCL/sycl-spirv-cconv-win.cpp
 create mode 100644 clang/test/SemaSYCL/sycl-spirv-host-adaptation.cpp

diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 389cc075a3a0b..8ff7b92a2b2df 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -101,9 +101,9 @@ static const unsigned SPIRDefIsGenMap[] = {
 
 // Base class for SPIR and SPIR-V target info.
 class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
+protected:
   std::unique_ptr<TargetInfo> HostTarget;
 
-protected:
   BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
       : TargetInfo(Triple) {
     assert((Triple.isSPIR() || Triple.isSPIRV()) &&
@@ -164,6 +164,18 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public 
TargetInfo {
       UseExplicitBitFieldAlignment = 
HostTarget->useExplicitBitFieldAlignment();
       ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
 
+      // Copy pointer-related type representations from host so that
+      // sizeof(size_t), sizeof(ptrdiff_t), sizeof(intptr_t) match
+      // between host and device. Without this, LLP64 hosts (Windows)
+      // get incorrect LP64-style defaults.
+      SizeType = HostTarget->getSizeType();
+      PtrDiffType = HostTarget->getPtrDiffType(LangAS::Default);
+      IntPtrType = HostTarget->getIntPtrType();
+
+      // Inherit Microsoft C mangling if the host uses it.
+      if (HostTarget->shouldUseMicrosoftCCforMangling())
+        UseMicrosoftManglingForC = true;
+
       // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, 
and
       // we need those macros to be identical on host and device, because 
(among
       // other things) they affect which standard library classes are defined,
@@ -195,6 +207,8 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public 
TargetInfo {
   }
 
   BuiltinVaListKind getBuiltinVaListKind() const override {
+    if (HostTarget)
+      return HostTarget->getBuiltinVaListKind();
     return TargetInfo::VoidPtrBuiltinVaList;
   }
 
@@ -204,8 +218,11 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public 
TargetInfo {
   }
 
   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override 
{
-    return (CC == CC_SpirFunction || CC == CC_DeviceKernel) ? CCCR_OK
-                                                            : CCCR_Warning;
+    if (CC == CC_SpirFunction || CC == CC_DeviceKernel)
+      return CCCR_OK;
+    if (HostTarget && HostTarget->checkCallingConvention(CC) == CCCR_OK)
+      return CCCR_OK;
+    return CCCR_Warning;
   }
 
   CallingConv getDefaultCallingConv() const override {
@@ -276,8 +293,10 @@ class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public 
SPIRTargetInfo {
     assert(Triple.getArch() == llvm::Triple::spir &&
            "Invalid architecture for 32-bit SPIR.");
     PointerWidth = PointerAlign = 32;
-    SizeType = TargetInfo::UnsignedInt;
-    PtrDiffType = IntPtrType = TargetInfo::SignedInt;
+    if (!HostTarget) {
+      SizeType = TargetInfo::UnsignedInt;
+      PtrDiffType = IntPtrType = TargetInfo::SignedInt;
+    }
     // SPIR32 has support for atomic ops if atomic extension is enabled.
     // Take the maximum because it's possible the Host supports wider types.
     MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64);
@@ -296,8 +315,10 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public 
SPIRTargetInfo {
     assert(Triple.getArch() == llvm::Triple::spir64 &&
            "Invalid architecture for 64-bit SPIR.");
     PointerWidth = PointerAlign = 64;
-    SizeType = TargetInfo::UnsignedLong;
-    PtrDiffType = IntPtrType = TargetInfo::SignedLong;
+    if (!HostTarget) {
+      SizeType = TargetInfo::UnsignedLong;
+      PtrDiffType = IntPtrType = TargetInfo::SignedLong;
+    }
     // SPIR64 has support for atomic ops if atomic extension is enabled.
     // Take the maximum because it's possible the Host supports wider types.
     MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64);
@@ -373,51 +394,57 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public 
BaseSPIRVTargetInfo {
                         MacroBuilder &Builder) const override;
 };
 
-class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo {
+// Common base for physical SPIR-V targets (spirv32/spirv64). Derives pointer
+// width from the host target when available; defaults to 32 or 64 based on
+// the target architecture.
+class LLVM_LIBRARY_VISIBILITY SPIRVPhysicalTargetInfo
+    : public BaseSPIRVTargetInfo {
 public:
-  SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+  SPIRVPhysicalTargetInfo(const llvm::Triple &Triple, const TargetOptions 
&Opts)
       : BaseSPIRVTargetInfo(Triple, Opts) {
-    assert(Triple.getArch() == llvm::Triple::spirv32 &&
-           "Invalid architecture for 32-bit SPIR-V.");
+    assert((Triple.getArch() == llvm::Triple::spirv32 ||
+            Triple.getArch() == llvm::Triple::spirv64) &&
+           "Invalid architecture for physical SPIR-V.");
     assert((getTriple().getOS() == llvm::Triple::UnknownOS ||
             getTriple().getOS() == llvm::Triple::ChipStar ||
             getTriple().getOS() == llvm::Triple::Vulkan) &&
-           "32-bit SPIR-V target must use unknown, chipstar, or vulkan OS");
+           "Physical SPIR-V target must use unknown, chipstar, or vulkan OS");
     assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
-           "32-bit SPIR-V target must use unknown environment type");
-    PointerWidth = PointerAlign = 32;
-    SizeType = TargetInfo::UnsignedInt;
-    PtrDiffType = IntPtrType = TargetInfo::SignedInt;
-    // SPIR-V has core support for atomic ops, and Int32 is always available;
-    // we take the maximum because it's possible the Host supports wider types.
+           "Physical SPIR-V target must use unknown environment type");
+
+    if (HostTarget) {
+      PointerWidth = PointerAlign = 
HostTarget->getPointerWidth(LangAS::Default);
+    } else {
+      PointerWidth = PointerAlign =
+          (Triple.getArch() == llvm::Triple::spirv32) ? 32 : 64;
+      if (PointerWidth == 32) {
+        SizeType = TargetInfo::UnsignedInt;
+        PtrDiffType = IntPtrType = TargetInfo::SignedInt;
+      } else {
+        SizeType = TargetInfo::UnsignedLong;
+        PtrDiffType = IntPtrType = TargetInfo::SignedLong;
+      }
+    }
     MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64);
     resetDataLayout();
   }
+};
+
+class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo
+    : public SPIRVPhysicalTargetInfo {
+public:
+  SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+      : SPIRVPhysicalTargetInfo(Triple, Opts) {}
 
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override;
 };
 
-class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {
+class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo
+    : public SPIRVPhysicalTargetInfo {
 public:
   SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
-      : BaseSPIRVTargetInfo(Triple, Opts) {
-    assert(Triple.getArch() == llvm::Triple::spirv64 &&
-           "Invalid architecture for 64-bit SPIR-V.");
-    assert((getTriple().getOS() == llvm::Triple::UnknownOS ||
-            getTriple().getOS() == llvm::Triple::ChipStar ||
-            getTriple().getOS() == llvm::Triple::Vulkan) &&
-           "64-bit SPIR-V target must use unknown, chipstar, or vulkan OS");
-    assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
-           "64-bit SPIR-V target must use unknown environment type");
-    PointerWidth = PointerAlign = 64;
-    SizeType = TargetInfo::UnsignedLong;
-    PtrDiffType = IntPtrType = TargetInfo::SignedLong;
-    // SPIR-V has core support for atomic ops, and Int64 is always available;
-    // we take the maximum because it's possible the Host supports wider types.
-    MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64);
-    resetDataLayout();
-  }
+      : SPIRVPhysicalTargetInfo(Triple, Opts) {}
 
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override;
diff --git a/clang/test/CodeGenSYCL/spirv-host-adaptation-mangling.cpp 
b/clang/test/CodeGenSYCL/spirv-host-adaptation-mangling.cpp
new file mode 100644
index 0000000000000..938b890fd7150
--- /dev/null
+++ b/clang/test/CodeGenSYCL/spirv-host-adaptation-mangling.cpp
@@ -0,0 +1,16 @@
+/// Tests UseMicrosoftManglingForC inheritance from the Windows host target.
+
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-pc-windows-msvc \
+// RUN:   -fsycl-is-device -emit-llvm -o - %s | FileCheck --check-prefix=WIN %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-unknown-linux-gnu \
+// RUN:   -fsycl-is-device -emit-llvm -o - %s | FileCheck --check-prefix=LINUX 
%s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown \
+// RUN:   -fsycl-is-device -emit-llvm -o - %s | FileCheck --check-prefix=LINUX 
%s
+
+[[clang::sycl_external]] int square(int x) { return x * x; }
+// WIN: define {{.*}} @_Z6squarei
+// LINUX: define {{.*}} @_Z6squarei
+
+extern "C" [[clang::sycl_external]] int cfunc(int x) { return x + 1; }
+// WIN: define {{.*}} @cfunc
+// LINUX: define {{.*}} @cfunc
diff --git a/clang/test/CodeGenSYCL/spirv-host-adaptation-new.cpp 
b/clang/test/CodeGenSYCL/spirv-host-adaptation-new.cpp
new file mode 100644
index 0000000000000..796c3ea7c5add
--- /dev/null
+++ b/clang/test/CodeGenSYCL/spirv-host-adaptation-new.cpp
@@ -0,0 +1,23 @@
+/// Tests operator new/delete mangling reflects the adapted SizeType.
+/// Itanium mangling encodes the type name: _Znwm (unsigned long) vs _Znwy
+/// (unsigned long long), even though both are 64-bit.
+
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-pc-windows-msvc \
+// RUN:   -fsycl-is-device -emit-llvm -o - %s | FileCheck --check-prefix=WIN %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-unknown-linux-gnu \
+// RUN:   -fsycl-is-device -emit-llvm -o - %s | FileCheck --check-prefix=LINUX 
%s
+
+typedef __SIZE_TYPE__ size_t;
+
+[[clang::sycl_external]] void *operator new(size_t n);
+[[clang::sycl_external]] void operator delete(void *p, size_t n) noexcept;
+
+[[clang::sycl_external]] void foo() {
+  int *p = new int;
+  delete p;
+}
+
+// WIN: declare {{.*}} @_Znwy(i64 noundef)
+// WIN: declare {{.*}} @_ZdlPvy(ptr addrspace(4) noundef, i64 noundef)
+// LINUX: declare {{.*}} @_Znwm(i64 noundef)
+// LINUX: declare {{.*}} @_ZdlPvm(ptr addrspace(4) noundef, i64 noundef)
diff --git a/clang/test/Preprocessor/spir-target-host-adaptation.cpp 
b/clang/test/Preprocessor/spir-target-host-adaptation.cpp
new file mode 100644
index 0000000000000..917ac8306a2ba
--- /dev/null
+++ b/clang/test/Preprocessor/spir-target-host-adaptation.cpp
@@ -0,0 +1,33 @@
+/// Tests legacy SPIR target adaptation of type properties from the host.
+
+// RUN: %clang_cc1 -triple spir64-unknown-unknown -aux-triple 
x86_64-unknown-linux-gnu \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=SPIR64-LINUX %s
+// RUN: %clang_cc1 -triple spir64-unknown-unknown -aux-triple 
x86_64-pc-windows-msvc \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=SPIR64-WIN %s
+// RUN: %clang_cc1 -triple spir-unknown-unknown -aux-triple 
i386-unknown-linux-gnu \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=SPIR32-LINUX %s
+// RUN: %clang_cc1 -triple spir64-unknown-unknown \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=SPIR64-NOHOST 
%s
+
+// SPIR64 + Linux (LP64)
+// SPIR64-LINUX-DAG: #define __SIZE_TYPE__ long unsigned int
+// SPIR64-LINUX-DAG: #define __PTRDIFF_TYPE__ long int
+// SPIR64-LINUX-DAG: #define __INTPTR_TYPE__ long int
+// SPIR64-LINUX-DAG: #define __SIZEOF_LONG__ 8
+
+// SPIR64 + Windows (LLP64)
+// SPIR64-WIN-DAG: #define __SIZE_TYPE__ long long unsigned int
+// SPIR64-WIN-DAG: #define __PTRDIFF_TYPE__ long long int
+// SPIR64-WIN-DAG: #define __INTPTR_TYPE__ long long int
+// SPIR64-WIN-DAG: #define __SIZEOF_LONG__ 4
+
+// SPIR32 + Linux i386 (ILP32)
+// SPIR32-LINUX-DAG: #define __SIZE_TYPE__ unsigned int
+// SPIR32-LINUX-DAG: #define __PTRDIFF_TYPE__ int
+// SPIR32-LINUX-DAG: #define __INTPTR_TYPE__ int
+// SPIR32-LINUX-DAG: #define __SIZEOF_POINTER__ 4
+
+// SPIR64 no host (defaults)
+// SPIR64-NOHOST-DAG: #define __SIZE_TYPE__ long unsigned int
+// SPIR64-NOHOST-DAG: #define __PTRDIFF_TYPE__ long int
+// SPIR64-NOHOST-DAG: #define __INTPTR_TYPE__ long int
diff --git a/clang/test/Preprocessor/spirv-host-adaptation-valist.cpp 
b/clang/test/Preprocessor/spirv-host-adaptation-valist.cpp
new file mode 100644
index 0000000000000..e3398dcc399a6
--- /dev/null
+++ b/clang/test/Preprocessor/spirv-host-adaptation-valist.cpp
@@ -0,0 +1,12 @@
+/// Tests that SPIRV64 compiles with different getBuiltinVaListKind() 
delegations.
+
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-unknown-linux-gnu \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=LINUX %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-pc-windows-msvc \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=WIN %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=NOHOST %s
+
+// LINUX: #define __SPIRV64__ 1
+// WIN: #define __SPIRV64__ 1
+// NOHOST: #define __SPIRV64__ 1
diff --git a/clang/test/Preprocessor/spirv-target-host-adaptation.cpp 
b/clang/test/Preprocessor/spirv-target-host-adaptation.cpp
new file mode 100644
index 0000000000000..ff77735a95df8
--- /dev/null
+++ b/clang/test/Preprocessor/spirv-target-host-adaptation.cpp
@@ -0,0 +1,70 @@
+/// Tests SPIR-V device target adaptation of SizeType, PtrDiffType, and
+/// IntPtrType from the host target via -aux-triple.
+
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-unknown-linux-gnu \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=LINUX64 %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-pc-windows-msvc \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=WIN64 %s
+// RUN: %clang_cc1 -triple spirv32-unknown-unknown -aux-triple 
i386-unknown-linux-gnu \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=LINUX32 %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=NOHOST64 %s
+// RUN: %clang_cc1 -triple spirv32-unknown-unknown \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=NOHOST32 %s
+
+// Linux x86_64 host (LP64)
+// LINUX64-DAG: #define __SIZE_TYPE__ long unsigned int
+// LINUX64-DAG: #define __PTRDIFF_TYPE__ long int
+// LINUX64-DAG: #define __INTPTR_TYPE__ long int
+// LINUX64-DAG: #define __SIZEOF_SIZE_T__ 8
+// LINUX64-DAG: #define __SIZEOF_PTRDIFF_T__ 8
+// LINUX64-DAG: #define __SIZEOF_LONG__ 8
+// LINUX64-DAG: #define __SIZEOF_POINTER__ 8
+
+// Windows x86_64 host (LLP64)
+// WIN64-DAG: #define __SIZE_TYPE__ long long unsigned int
+// WIN64-DAG: #define __PTRDIFF_TYPE__ long long int
+// WIN64-DAG: #define __INTPTR_TYPE__ long long int
+// WIN64-DAG: #define __SIZEOF_SIZE_T__ 8
+// WIN64-DAG: #define __SIZEOF_PTRDIFF_T__ 8
+// WIN64-DAG: #define __SIZEOF_LONG__ 4
+// WIN64-DAG: #define __SIZEOF_POINTER__ 8
+
+// Linux i386 host (ILP32)
+// LINUX32-DAG: #define __SIZE_TYPE__ unsigned int
+// LINUX32-DAG: #define __PTRDIFF_TYPE__ int
+// LINUX32-DAG: #define __INTPTR_TYPE__ int
+// LINUX32-DAG: #define __SIZEOF_SIZE_T__ 4
+// LINUX32-DAG: #define __SIZEOF_PTRDIFF_T__ 4
+// LINUX32-DAG: #define __SIZEOF_POINTER__ 4
+
+// No host (SPIRV64 defaults)
+// NOHOST64-DAG: #define __SIZE_TYPE__ long unsigned int
+// NOHOST64-DAG: #define __PTRDIFF_TYPE__ long int
+// NOHOST64-DAG: #define __INTPTR_TYPE__ long int
+// NOHOST64-DAG: #define __SIZEOF_SIZE_T__ 8
+// NOHOST64-DAG: #define __SIZEOF_PTRDIFF_T__ 8
+// NOHOST64-DAG: #define __SIZEOF_POINTER__ 8
+
+// No host (SPIRV32 defaults)
+// NOHOST32-DAG: #define __SIZE_TYPE__ unsigned int
+// NOHOST32-DAG: #define __PTRDIFF_TYPE__ int
+// NOHOST32-DAG: #define __INTPTR_TYPE__ int
+// NOHOST32-DAG: #define __SIZEOF_SIZE_T__ 4
+// NOHOST32-DAG: #define __SIZEOF_PTRDIFF_T__ 4
+// NOHOST32-DAG: #define __SIZEOF_POINTER__ 4
+
+// Aux-target OS macros
+// WIN64-DAG: #define _WIN32 1
+// WIN64-DAG: #define _WIN64 1
+// LINUX64-DAG: #define __linux__ 1
+
+// SPIRV device macros always present
+// LINUX64-DAG: #define __SPIRV__ 1
+// LINUX64-DAG: #define __SPIRV64__ 1
+// WIN64-DAG: #define __SPIRV__ 1
+// WIN64-DAG: #define __SPIRV64__ 1
+// NOHOST64-DAG: #define __SPIRV__ 1
+// NOHOST64-DAG: #define __SPIRV64__ 1
+// NOHOST32-DAG: #define __SPIRV__ 1
+// NOHOST32-DAG: #define __SPIRV32__ 1
diff --git a/clang/test/SemaSYCL/sycl-spirv-cconv-nohost.cpp 
b/clang/test/SemaSYCL/sycl-spirv-cconv-nohost.cpp
new file mode 100644
index 0000000000000..68a59a0d190b2
--- /dev/null
+++ b/clang/test/SemaSYCL/sycl-spirv-cconv-nohost.cpp
@@ -0,0 +1,8 @@
+/// Tests that SPIRV64 warns on non-SPIR-V calling conventions without a host.
+
+// RUN: %clang_cc1 -fsycl-is-device \
+// RUN:   -triple spirv64-unknown-unknown \
+// RUN:   -fsyntax-only -verify %s
+
+void __vectorcall vector_func(float x, float y) {} // expected-warning 
{{'__vectorcall' calling convention is not supported for this target}}
+void default_func(int x) {}
diff --git a/clang/test/SemaSYCL/sycl-spirv-cconv-win.cpp 
b/clang/test/SemaSYCL/sycl-spirv-cconv-win.cpp
new file mode 100644
index 0000000000000..11821d3c212bf
--- /dev/null
+++ b/clang/test/SemaSYCL/sycl-spirv-cconv-win.cpp
@@ -0,0 +1,18 @@
+/// Tests that SPIRV64 accepts Windows calling conventions with Windows 
aux-triple.
+
+// RUN: %clang_cc1 -fsycl-is-device \
+// RUN:   -triple spirv64-unknown-unknown -aux-triple x86_64-pc-windows-msvc \
+// RUN:   -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+
+void __vectorcall vector_func(float x, float y) {}
+void __regcall regcall_func(int x) {}
+void __stdcall stdcall_func(int x) {}
+void default_func(int x) {}
+
+typedef void (__vectorcall *VecFnPtr)(float, float);
+typedef void (__regcall *RegFnPtr)(int);
+
+VecFnPtr vfp = &vector_func;
+RegFnPtr rfp = &regcall_func;
diff --git a/clang/test/SemaSYCL/sycl-spirv-host-adaptation.cpp 
b/clang/test/SemaSYCL/sycl-spirv-host-adaptation.cpp
new file mode 100644
index 0000000000000..d37428236ba29
--- /dev/null
+++ b/clang/test/SemaSYCL/sycl-spirv-host-adaptation.cpp
@@ -0,0 +1,18 @@
+/// Tests SPIRV64 with Windows MSVC aux-triple: LLP64 type sizes.
+// RUN: %clang_cc1 -fsycl-is-device \
+// RUN:   -triple spirv64-unknown-unknown -aux-triple x86_64-pc-windows-msvc \
+// RUN:   -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+
+static_assert(sizeof(void *) == 8, "pointer should be 64-bit on spirv64");
+static_assert(sizeof(long) == 4, "long should be 32-bit with Windows 
aux-triple");
+
+typedef __SIZE_TYPE__ size_t_type;
+static_assert(sizeof(size_t_type) == 8, "size_t must be 64-bit on Win64 
SPIRV64");
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t_type;
+static_assert(sizeof(ptrdiff_t_type) == 8, "ptrdiff_t must be 64-bit on Win64 
SPIRV64");
+
+typedef __INTPTR_TYPE__ intptr_t_type;
+static_assert(sizeof(intptr_t_type) == 8, "intptr_t must be 64-bit on Win64 
SPIRV64");

>From bfc550a5d9b172dd2a48f6cbb5474f5e3da27aca Mon Sep 17 00:00:00 2001
From: Sindhu Chittireddy <[email protected]>
Date: Wed, 8 Jul 2026 04:33:26 -0700
Subject: [PATCH 2/4] Fix formatting error

---
 clang/lib/Basic/Targets/SPIR.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 0755bb64dc837..f235059db05eb 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -409,7 +409,8 @@ class LLVM_LIBRARY_VISIBILITY SPIRVPhysicalTargetInfo
            "Physical SPIR-V target must use unknown environment type");
 
     if (HostTarget) {
-      PointerWidth = PointerAlign = 
HostTarget->getPointerWidth(LangAS::Default);
+      PointerWidth = PointerAlign =
+          HostTarget->getPointerWidth(LangAS::Default);
     } else {
       PointerWidth = PointerAlign =
           (Triple.getArch() == llvm::Triple::spirv32) ? 32 : 64;

>From b3238fd1f8fe92b4d5bd36671448481caea6aa82 Mon Sep 17 00:00:00 2001
From: Sindhu Chittireddy <[email protected]>
Date: Thu, 9 Jul 2026 14:22:38 -0700
Subject: [PATCH 3/4] Move test folders and expand va_list test

---
 .../spirv-host-adaptation-mangling.cpp        |  0
 .../CodeGenSYCL/spirv-host-adaptation-new.cpp | 23 -----------
 .../spirv-host-adaptation-valist.cpp          |  5 ++-
 .../spirv-target-host-adaptation.cpp          |  5 ++-
 .../spirv-cconv-nohost.cpp}                   |  0
 .../spirv-cconv-win.cpp}                      |  0
 .../spirv-host-adaptation-valist.cpp          | 41 +++++++++++++++++++
 .../spirv-host-adaptation.cpp}                |  0
 8 files changed, 49 insertions(+), 25 deletions(-)
 rename clang/test/{CodeGenSYCL => 
CodeGenSPIRV}/spirv-host-adaptation-mangling.cpp (100%)
 delete mode 100644 clang/test/CodeGenSYCL/spirv-host-adaptation-new.cpp
 rename clang/test/{SemaSYCL/sycl-spirv-cconv-nohost.cpp => 
SemaSPIRV/spirv-cconv-nohost.cpp} (100%)
 rename clang/test/{SemaSYCL/sycl-spirv-cconv-win.cpp => 
SemaSPIRV/spirv-cconv-win.cpp} (100%)
 create mode 100644 clang/test/SemaSPIRV/spirv-host-adaptation-valist.cpp
 rename clang/test/{SemaSYCL/sycl-spirv-host-adaptation.cpp => 
SemaSPIRV/spirv-host-adaptation.cpp} (100%)

diff --git a/clang/test/CodeGenSYCL/spirv-host-adaptation-mangling.cpp 
b/clang/test/CodeGenSPIRV/spirv-host-adaptation-mangling.cpp
similarity index 100%
rename from clang/test/CodeGenSYCL/spirv-host-adaptation-mangling.cpp
rename to clang/test/CodeGenSPIRV/spirv-host-adaptation-mangling.cpp
diff --git a/clang/test/CodeGenSYCL/spirv-host-adaptation-new.cpp 
b/clang/test/CodeGenSYCL/spirv-host-adaptation-new.cpp
deleted file mode 100644
index 796c3ea7c5add..0000000000000
--- a/clang/test/CodeGenSYCL/spirv-host-adaptation-new.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-/// Tests operator new/delete mangling reflects the adapted SizeType.
-/// Itanium mangling encodes the type name: _Znwm (unsigned long) vs _Znwy
-/// (unsigned long long), even though both are 64-bit.
-
-// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-pc-windows-msvc \
-// RUN:   -fsycl-is-device -emit-llvm -o - %s | FileCheck --check-prefix=WIN %s
-// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-unknown-linux-gnu \
-// RUN:   -fsycl-is-device -emit-llvm -o - %s | FileCheck --check-prefix=LINUX 
%s
-
-typedef __SIZE_TYPE__ size_t;
-
-[[clang::sycl_external]] void *operator new(size_t n);
-[[clang::sycl_external]] void operator delete(void *p, size_t n) noexcept;
-
-[[clang::sycl_external]] void foo() {
-  int *p = new int;
-  delete p;
-}
-
-// WIN: declare {{.*}} @_Znwy(i64 noundef)
-// WIN: declare {{.*}} @_ZdlPvy(ptr addrspace(4) noundef, i64 noundef)
-// LINUX: declare {{.*}} @_Znwm(i64 noundef)
-// LINUX: declare {{.*}} @_ZdlPvm(ptr addrspace(4) noundef, i64 noundef)
diff --git a/clang/test/Preprocessor/spirv-host-adaptation-valist.cpp 
b/clang/test/Preprocessor/spirv-host-adaptation-valist.cpp
index e3398dcc399a6..c682ba3438565 100644
--- a/clang/test/Preprocessor/spirv-host-adaptation-valist.cpp
+++ b/clang/test/Preprocessor/spirv-host-adaptation-valist.cpp
@@ -1,12 +1,15 @@
-/// Tests that SPIRV64 compiles with different getBuiltinVaListKind() 
delegations.
+/// Tests that preprocessing succeeds with different getBuiltinVaListKind() 
delegations.
 
 // RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-unknown-linux-gnu \
 // RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=LINUX %s
 // RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-pc-windows-msvc \
 // RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=WIN %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
aarch64-unknown-linux-gnu \
+// RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=AARCH64 %s
 // RUN: %clang_cc1 -triple spirv64-unknown-unknown \
 // RUN:   -fsycl-is-device -E -dM %s | FileCheck --check-prefix=NOHOST %s
 
 // LINUX: #define __SPIRV64__ 1
 // WIN: #define __SPIRV64__ 1
+// AARCH64: #define __SPIRV64__ 1
 // NOHOST: #define __SPIRV64__ 1
diff --git a/clang/test/Preprocessor/spirv-target-host-adaptation.cpp 
b/clang/test/Preprocessor/spirv-target-host-adaptation.cpp
index ff77735a95df8..786059fee4cf0 100644
--- a/clang/test/Preprocessor/spirv-target-host-adaptation.cpp
+++ b/clang/test/Preprocessor/spirv-target-host-adaptation.cpp
@@ -54,10 +54,13 @@
 // NOHOST32-DAG: #define __SIZEOF_PTRDIFF_T__ 4
 // NOHOST32-DAG: #define __SIZEOF_POINTER__ 4
 
-// Aux-target OS macros
+// Aux-target OS and arch macros
 // WIN64-DAG: #define _WIN32 1
 // WIN64-DAG: #define _WIN64 1
+// WIN64-DAG: #define _M_X64 100
+// WIN64-DAG: #define _M_AMD64 100
 // LINUX64-DAG: #define __linux__ 1
+// LINUX64-DAG: #define __x86_64__ 1
 
 // SPIRV device macros always present
 // LINUX64-DAG: #define __SPIRV__ 1
diff --git a/clang/test/SemaSYCL/sycl-spirv-cconv-nohost.cpp 
b/clang/test/SemaSPIRV/spirv-cconv-nohost.cpp
similarity index 100%
rename from clang/test/SemaSYCL/sycl-spirv-cconv-nohost.cpp
rename to clang/test/SemaSPIRV/spirv-cconv-nohost.cpp
diff --git a/clang/test/SemaSYCL/sycl-spirv-cconv-win.cpp 
b/clang/test/SemaSPIRV/spirv-cconv-win.cpp
similarity index 100%
rename from clang/test/SemaSYCL/sycl-spirv-cconv-win.cpp
rename to clang/test/SemaSPIRV/spirv-cconv-win.cpp
diff --git a/clang/test/SemaSPIRV/spirv-host-adaptation-valist.cpp 
b/clang/test/SemaSPIRV/spirv-host-adaptation-valist.cpp
new file mode 100644
index 0000000000000..b9430cb174363
--- /dev/null
+++ b/clang/test/SemaSPIRV/spirv-host-adaptation-valist.cpp
@@ -0,0 +1,41 @@
+/// Tests that getBuiltinVaListKind() delegates to the host target, verified
+/// via sizeof(__builtin_va_list) and struct layout containing va_list.
+
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-unknown-linux-gnu \
+// RUN:   -fsycl-is-device -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
x86_64-pc-windows-msvc \
+// RUN:   -fsycl-is-device -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple 
aarch64-unknown-linux-gnu \
+// RUN:   -fsycl-is-device -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple spirv64-unknown-unknown \
+// RUN:   -fsycl-is-device -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+
+struct has_valist { int x; __builtin_va_list ap; int y; };
+
+#if defined(_WIN32)
+// Windows x86_64: CharPtrBuiltinVaList (char*)
+static_assert(sizeof(__builtin_va_list) == 8, "Windows: va_list is char*");
+static_assert(sizeof(has_valist) == 24, "Windows: struct layout with char* 
va_list");
+static_assert(__builtin_offsetof(has_valist, y) == 16,
+              "Windows: field after char* va_list");
+#elif defined(__aarch64__)
+// AArch64 Linux: AArch64ABIBuiltinVaList (struct, 32 bytes)
+static_assert(sizeof(__builtin_va_list) == 32, "AArch64: va_list is struct");
+static_assert(sizeof(has_valist) == 48, "AArch64: struct layout with 32-byte 
va_list");
+static_assert(__builtin_offsetof(has_valist, y) == 40,
+              "AArch64: field after 32-byte va_list");
+#elif defined(__x86_64__)
+// x86_64 Linux: X86_64ABIBuiltinVaList (struct __va_list_tag, 24 bytes)
+static_assert(sizeof(__builtin_va_list) == 24, "Linux x86_64: va_list is 
struct");
+static_assert(sizeof(has_valist) == 40, "Linux x86_64: struct layout with 
24-byte va_list");
+static_assert(__builtin_offsetof(has_valist, y) == 32,
+              "Linux x86_64: field after 24-byte va_list");
+#else
+// No host: VoidPtrBuiltinVaList (void*)
+static_assert(sizeof(__builtin_va_list) == 8, "No host: va_list is void*");
+static_assert(sizeof(has_valist) == 24, "No host: struct layout with void* 
va_list");
+static_assert(__builtin_offsetof(has_valist, y) == 16,
+              "No host: field after void* va_list");
+#endif
diff --git a/clang/test/SemaSYCL/sycl-spirv-host-adaptation.cpp 
b/clang/test/SemaSPIRV/spirv-host-adaptation.cpp
similarity index 100%
rename from clang/test/SemaSYCL/sycl-spirv-host-adaptation.cpp
rename to clang/test/SemaSPIRV/spirv-host-adaptation.cpp

>From 7bed39c447fcea0b6453d3df1077bc5640be546f Mon Sep 17 00:00:00 2001
From: Sindhu Chittireddy <[email protected]>
Date: Thu, 9 Jul 2026 22:48:10 -0700
Subject: [PATCH 4/4] Get rid of calling convention changes to follow-up later

---
 clang/lib/Basic/Targets/SPIR.h              |  7 ++-----
 clang/test/SemaSPIRV/spirv-cconv-nohost.cpp |  8 --------
 clang/test/SemaSPIRV/spirv-cconv-win.cpp    | 18 ------------------
 3 files changed, 2 insertions(+), 31 deletions(-)
 delete mode 100644 clang/test/SemaSPIRV/spirv-cconv-nohost.cpp
 delete mode 100644 clang/test/SemaSPIRV/spirv-cconv-win.cpp

diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index f235059db05eb..cb3dccdb3a682 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -214,11 +214,8 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public 
TargetInfo {
   }
 
   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override 
{
-    if (CC == CC_SpirFunction || CC == CC_DeviceKernel)
-      return CCCR_OK;
-    if (HostTarget && HostTarget->checkCallingConvention(CC) == CCCR_OK)
-      return CCCR_OK;
-    return CCCR_Warning;
+    return (CC == CC_SpirFunction || CC == CC_DeviceKernel) ? CCCR_OK
+                                                           : CCCR_Warning;
   }
 
   CallingConv getDefaultCallingConv() const override {
diff --git a/clang/test/SemaSPIRV/spirv-cconv-nohost.cpp 
b/clang/test/SemaSPIRV/spirv-cconv-nohost.cpp
deleted file mode 100644
index 68a59a0d190b2..0000000000000
--- a/clang/test/SemaSPIRV/spirv-cconv-nohost.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-/// Tests that SPIRV64 warns on non-SPIR-V calling conventions without a host.
-
-// RUN: %clang_cc1 -fsycl-is-device \
-// RUN:   -triple spirv64-unknown-unknown \
-// RUN:   -fsyntax-only -verify %s
-
-void __vectorcall vector_func(float x, float y) {} // expected-warning 
{{'__vectorcall' calling convention is not supported for this target}}
-void default_func(int x) {}
diff --git a/clang/test/SemaSPIRV/spirv-cconv-win.cpp 
b/clang/test/SemaSPIRV/spirv-cconv-win.cpp
deleted file mode 100644
index 11821d3c212bf..0000000000000
--- a/clang/test/SemaSPIRV/spirv-cconv-win.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/// Tests that SPIRV64 accepts Windows calling conventions with Windows 
aux-triple.
-
-// RUN: %clang_cc1 -fsycl-is-device \
-// RUN:   -triple spirv64-unknown-unknown -aux-triple x86_64-pc-windows-msvc \
-// RUN:   -fsyntax-only -verify %s
-
-// expected-no-diagnostics
-
-void __vectorcall vector_func(float x, float y) {}
-void __regcall regcall_func(int x) {}
-void __stdcall stdcall_func(int x) {}
-void default_func(int x) {}
-
-typedef void (__vectorcall *VecFnPtr)(float, float);
-typedef void (__regcall *RegFnPtr)(int);
-
-VecFnPtr vfp = &vector_func;
-RegFnPtr rfp = &regcall_func;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to