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 01/11] [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 = ®call_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 02/11] 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 03/11] 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 04/11] 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 = ®call_func; >From 39032404a221254a8ed826d5f5d666cad9d7fd6b Mon Sep 17 00:00:00 2001 From: Sindhu Chittireddy <[email protected]> Date: Thu, 9 Jul 2026 23:03:28 -0700 Subject: [PATCH 05/11] Fix formatting --- clang/lib/Basic/Targets/SPIR.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index cb3dccdb3a682..a9148fc49b124 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -215,7 +215,7 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo { CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { return (CC == CC_SpirFunction || CC == CC_DeviceKernel) ? CCCR_OK - : CCCR_Warning; + : CCCR_Warning; } CallingConv getDefaultCallingConv() const override { >From 39dc9b5a27392faa82ef26c2b29e57b11171b3fc Mon Sep 17 00:00:00 2001 From: Sindhu Chittireddy <[email protected]> Date: Sun, 12 Jul 2026 13:54:32 -0700 Subject: [PATCH 06/11] Address review comments --- clang/lib/Basic/Targets/SPIR.h | 87 ++++++++++--------- .../spirv-host-adaptation-valist.cpp | 24 +++++ ...on.cpp => spir-host-adaptation-macros.cpp} | 3 + ...n.cpp => spirv-host-adaptation-macros.cpp} | 0 .../SemaSPIRV/spirv-host-adaptation-types.cpp | 73 ++++++++++++++++ .../spirv-host-adaptation-valist.cpp | 38 +++----- .../test/SemaSPIRV/spirv-host-adaptation.cpp | 18 ---- 7 files changed, 160 insertions(+), 83 deletions(-) create mode 100644 clang/test/CodeGenSPIRV/spirv-host-adaptation-valist.cpp rename clang/test/Preprocessor/{spir-target-host-adaptation.cpp => spir-host-adaptation-macros.cpp} (91%) rename clang/test/Preprocessor/{spirv-target-host-adaptation.cpp => spirv-host-adaptation-macros.cpp} (100%) create mode 100644 clang/test/SemaSPIRV/spirv-host-adaptation-types.cpp delete mode 100644 clang/test/SemaSPIRV/spirv-host-adaptation.cpp diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index a9148fc49b124..9bace42b27d38 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -164,10 +164,12 @@ 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. + // Copy pointer width and related type representations from host so + // that sizeof(void*), sizeof(size_t), sizeof(ptrdiff_t), and + // sizeof(intptr_t) match between host and device. Without this, + // LLP64 hosts (Windows) get incorrect LP64-style defaults. + PointerWidth = PointerAlign = + HostTarget->getPointerWidth(LangAS::Default); SizeType = HostTarget->getSizeType(); PtrDiffType = HostTarget->getPtrDiffType(LangAS::Default); IntPtrType = HostTarget->getIntPtrType(); @@ -285,10 +287,13 @@ class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { : SPIRTargetInfo(Triple, Opts) { assert(Triple.getArch() == llvm::Triple::spir && "Invalid architecture for 32-bit SPIR."); - PointerWidth = PointerAlign = 32; if (!HostTarget) { + PointerWidth = PointerAlign = 32; SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; + } else { + assert(PointerWidth == 32 && + "32-bit SPIR target requires a 32-bit host"); } // SPIR32 has support for atomic ops if atomic extension is enabled. // Take the maximum because it's possible the Host supports wider types. @@ -307,10 +312,13 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo { : SPIRTargetInfo(Triple, Opts) { assert(Triple.getArch() == llvm::Triple::spir64 && "Invalid architecture for 64-bit SPIR."); - PointerWidth = PointerAlign = 64; if (!HostTarget) { + PointerWidth = PointerAlign = 64; SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; + } else { + assert(PointerWidth == 64 && + "64-bit SPIR target requires a 64-bit host"); } // SPIR64 has support for atomic ops if atomic extension is enabled. // Take the maximum because it's possible the Host supports wider types. @@ -387,58 +395,57 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo { MacroBuilder &Builder) const override; }; -// 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 { +class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo { public: - SPIRVPhysicalTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : BaseSPIRVTargetInfo(Triple, Opts) { - assert((Triple.getArch() == llvm::Triple::spirv32 || - Triple.getArch() == llvm::Triple::spirv64) && - "Invalid architecture for physical SPIR-V."); + assert(Triple.getArch() == llvm::Triple::spirv32 && + "Invalid architecture for 32-bit SPIR-V."); assert((getTriple().getOS() == llvm::Triple::UnknownOS || getTriple().getOS() == llvm::Triple::ChipStar || getTriple().getOS() == llvm::Triple::Vulkan) && - "Physical SPIR-V target must use unknown, chipstar, or vulkan OS"); + "32-bit SPIR-V target must use unknown, chipstar, or vulkan OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && - "Physical SPIR-V target must use unknown environment type"); - - if (HostTarget) { - PointerWidth = PointerAlign = - HostTarget->getPointerWidth(LangAS::Default); + "32-bit SPIR-V target must use unknown environment type"); + if (!HostTarget) { + PointerWidth = PointerAlign = 32; + SizeType = TargetInfo::UnsignedInt; + PtrDiffType = IntPtrType = TargetInfo::SignedInt; } 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; - } + assert(PointerWidth == 32 && + "32-bit SPIR-V target requires a 32-bit host"); } 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 SPIRVPhysicalTargetInfo { +class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo { public: SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : SPIRVPhysicalTargetInfo(Triple, 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"); + if (!HostTarget) { + PointerWidth = PointerAlign = 64; + SizeType = TargetInfo::UnsignedLong; + PtrDiffType = IntPtrType = TargetInfo::SignedLong; + } else { + assert(PointerWidth == 64 && + "64-bit SPIR-V target requires a 64-bit host"); + } + MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64); + resetDataLayout(); + } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; diff --git a/clang/test/CodeGenSPIRV/spirv-host-adaptation-valist.cpp b/clang/test/CodeGenSPIRV/spirv-host-adaptation-valist.cpp new file mode 100644 index 0000000000000..d926e30376b18 --- /dev/null +++ b/clang/test/CodeGenSPIRV/spirv-host-adaptation-valist.cpp @@ -0,0 +1,24 @@ +/// Tests that va_list layout matches the host target's getBuiltinVaListKind(). + +// 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 -aux-triple x86_64-pc-windows-msvc \ +// RUN: -fsycl-is-device -emit-llvm -o - %s | FileCheck --check-prefix=WINDOWS %s + +[[clang::sycl_external]] int f(int n, ...) { + __builtin_va_list ap1, ap2; + __builtin_va_start(ap1, n); + int v = __builtin_va_arg(ap1, int); + __builtin_va_copy(ap2, ap1); + __builtin_va_end(ap1); + __builtin_va_end(ap2); + return v; +} + +// LINUX: define {{.*}} i32 @_Z1fiz(i32 noundef %n, ...) {{.*}} { +// LINUX: %ap1 = alloca [1 x %struct.__va_list_tag], align 8 +// LINUX: %ap2 = alloca [1 x %struct.__va_list_tag], align 8 + +// WINDOWS: define {{.*}} i32 @_Z1fiz(i32 noundef %n, ...) {{.*}} { +// WINDOWS: %ap1 = alloca ptr addrspace(4), align 8 +// WINDOWS: %ap2 = alloca ptr addrspace(4), align 8 diff --git a/clang/test/Preprocessor/spir-target-host-adaptation.cpp b/clang/test/Preprocessor/spir-host-adaptation-macros.cpp similarity index 91% rename from clang/test/Preprocessor/spir-target-host-adaptation.cpp rename to clang/test/Preprocessor/spir-host-adaptation-macros.cpp index 917ac8306a2ba..c8e29ff60b250 100644 --- a/clang/test/Preprocessor/spir-target-host-adaptation.cpp +++ b/clang/test/Preprocessor/spir-host-adaptation-macros.cpp @@ -14,12 +14,14 @@ // SPIR64-LINUX-DAG: #define __PTRDIFF_TYPE__ long int // SPIR64-LINUX-DAG: #define __INTPTR_TYPE__ long int // SPIR64-LINUX-DAG: #define __SIZEOF_LONG__ 8 +// SPIR64-LINUX-DAG: #define __SIZEOF_POINTER__ 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 +// SPIR64-WIN-DAG: #define __SIZEOF_POINTER__ 8 // SPIR32 + Linux i386 (ILP32) // SPIR32-LINUX-DAG: #define __SIZE_TYPE__ unsigned int @@ -31,3 +33,4 @@ // 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 +// SPIR64-NOHOST-DAG: #define __SIZEOF_POINTER__ 8 diff --git a/clang/test/Preprocessor/spirv-target-host-adaptation.cpp b/clang/test/Preprocessor/spirv-host-adaptation-macros.cpp similarity index 100% rename from clang/test/Preprocessor/spirv-target-host-adaptation.cpp rename to clang/test/Preprocessor/spirv-host-adaptation-macros.cpp diff --git a/clang/test/SemaSPIRV/spirv-host-adaptation-types.cpp b/clang/test/SemaSPIRV/spirv-host-adaptation-types.cpp new file mode 100644 index 0000000000000..8df8e4a3f508f --- /dev/null +++ b/clang/test/SemaSPIRV/spirv-host-adaptation-types.cpp @@ -0,0 +1,73 @@ +/// Tests that SPIR-V device targets adapt pointer and integer type sizes +/// from the host target via -aux-triple. + +// RUN: %clang_cc1 -fsycl-is-device \ +// RUN: -triple spirv64-unknown-unknown -aux-triple x86_64-unknown-linux-gnu \ +// RUN: -fsyntax-only -verify=linux64 %s +// RUN: %clang_cc1 -fsycl-is-device \ +// RUN: -triple spirv64-unknown-unknown -aux-triple x86_64-pc-windows-msvc \ +// RUN: -fsyntax-only -verify=win64 %s +// RUN: %clang_cc1 -fsycl-is-device \ +// RUN: -triple spirv32-unknown-unknown -aux-triple i386-unknown-linux-gnu \ +// RUN: -fsyntax-only -verify=linux32 %s +// RUN: %clang_cc1 -fsycl-is-device \ +// RUN: -triple spirv64-unknown-unknown \ +// RUN: -fsyntax-only -verify=nohost64 %s +// RUN: %clang_cc1 -fsycl-is-device \ +// RUN: -triple spirv32-unknown-unknown \ +// RUN: -fsyntax-only -verify=nohost32 %s + +// linux64-no-diagnostics +// win64-no-diagnostics +// linux32-no-diagnostics +// nohost64-no-diagnostics +// nohost32-no-diagnostics + +typedef __SIZE_TYPE__ size_t_type; +typedef __PTRDIFF_TYPE__ ptrdiff_t_type; +typedef __INTPTR_TYPE__ intptr_t_type; + +// --- SPIRV64 + Linux x86_64 (LP64): long=8, pointer=8 --- +#if __SPIRV64__ && defined(__linux__) && defined(__x86_64__) +static_assert(sizeof(void *) == 8, "pointer should be 64-bit"); +static_assert(sizeof(long) == 8, "long should be 64-bit with Linux LP64"); +static_assert(sizeof(size_t_type) == 8, "size_t must be 64-bit"); +static_assert(sizeof(ptrdiff_t_type) == 8, "ptrdiff_t must be 64-bit"); +static_assert(sizeof(intptr_t_type) == 8, "intptr_t must be 64-bit"); +#endif + +// --- SPIRV64 + Windows x86_64 (LLP64): long=4, pointer=8 --- +#if __SPIRV64__ && defined(_WIN64) +static_assert(sizeof(void *) == 8, "pointer should be 64-bit"); +static_assert(sizeof(long) == 4, "long should be 32-bit with Windows LLP64"); +static_assert(sizeof(size_t_type) == 8, "size_t must be 64-bit"); +static_assert(sizeof(ptrdiff_t_type) == 8, "ptrdiff_t must be 64-bit"); +static_assert(sizeof(intptr_t_type) == 8, "intptr_t must be 64-bit"); +#endif + +// --- SPIRV32 + Linux i386 (ILP32): long=4, pointer=4 --- +#if __SPIRV32__ && defined(__linux__) && defined(__i386__) +static_assert(sizeof(void *) == 4, "pointer should be 32-bit"); +static_assert(sizeof(long) == 4, "long should be 32-bit with ILP32"); +static_assert(sizeof(size_t_type) == 4, "size_t must be 32-bit"); +static_assert(sizeof(ptrdiff_t_type) == 4, "ptrdiff_t must be 32-bit"); +static_assert(sizeof(intptr_t_type) == 4, "intptr_t must be 32-bit"); +#endif + +// --- SPIRV64 no host (defaults match LP64) --- +#if __SPIRV64__ && !defined(__linux__) && !defined(_WIN64) +static_assert(sizeof(void *) == 8, "pointer should be 64-bit"); +static_assert(sizeof(long) == 8, "long should be 64-bit with default LP64"); +static_assert(sizeof(size_t_type) == 8, "size_t must be 64-bit"); +static_assert(sizeof(ptrdiff_t_type) == 8, "ptrdiff_t must be 64-bit"); +static_assert(sizeof(intptr_t_type) == 8, "intptr_t must be 64-bit"); +#endif + +// --- SPIRV32 no host (pointer=4, but long stays at base default=8) --- +#if __SPIRV32__ && !defined(__linux__) && !defined(_WIN64) +static_assert(sizeof(void *) == 4, "pointer should be 32-bit"); +static_assert(sizeof(long) == 8, "long defaults to 64-bit without a host"); +static_assert(sizeof(size_t_type) == 4, "size_t must be 32-bit"); +static_assert(sizeof(ptrdiff_t_type) == 4, "ptrdiff_t must be 32-bit"); +static_assert(sizeof(intptr_t_type) == 4, "intptr_t must be 32-bit"); +#endif diff --git a/clang/test/SemaSPIRV/spirv-host-adaptation-valist.cpp b/clang/test/SemaSPIRV/spirv-host-adaptation-valist.cpp index b9430cb174363..5959aa5262dc9 100644 --- a/clang/test/SemaSPIRV/spirv-host-adaptation-valist.cpp +++ b/clang/test/SemaSPIRV/spirv-host-adaptation-valist.cpp @@ -1,5 +1,4 @@ -/// Tests that getBuiltinVaListKind() delegates to the host target, verified -/// via sizeof(__builtin_va_list) and struct layout containing va_list. +/// Tests that getBuiltinVaListKind() delegates to the host target. // RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple x86_64-unknown-linux-gnu \ // RUN: -fsycl-is-device -fsyntax-only -verify %s @@ -12,30 +11,19 @@ // expected-no-diagnostics -struct has_valist { int x; __builtin_va_list ap; int y; }; +template<typename T, typename U> +struct same_type; +template<typename T> +struct same_type<T, T> { + using type = int; +}; +template<typename T, typename U, typename = typename same_type<T, U>::type> +constexpr bool is_same_type(int) { return true; } +template<typename T, typename U> +constexpr bool is_same_type(...) { return false; } #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"); +static_assert(is_same_type<__builtin_va_list, char*>(0)); #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"); +static_assert(!is_same_type<__builtin_va_list, char*>(0)); #endif diff --git a/clang/test/SemaSPIRV/spirv-host-adaptation.cpp b/clang/test/SemaSPIRV/spirv-host-adaptation.cpp deleted file mode 100644 index d37428236ba29..0000000000000 --- a/clang/test/SemaSPIRV/spirv-host-adaptation.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/// 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 4922bfe2661ab894c761c76def8a1d26b774b43b Mon Sep 17 00:00:00 2001 From: Sindhu Chittireddy <[email protected]> Date: Sun, 12 Jul 2026 14:12:25 -0700 Subject: [PATCH 07/11] Remove mangling changes. --- clang/lib/Basic/Targets/SPIR.h | 4 ---- .../spirv-host-adaptation-mangling.cpp | 16 ---------------- 2 files changed, 20 deletions(-) delete mode 100644 clang/test/CodeGenSPIRV/spirv-host-adaptation-mangling.cpp diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 9bace42b27d38..2dcf07f187e85 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -174,10 +174,6 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo { 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, diff --git a/clang/test/CodeGenSPIRV/spirv-host-adaptation-mangling.cpp b/clang/test/CodeGenSPIRV/spirv-host-adaptation-mangling.cpp deleted file mode 100644 index 938b890fd7150..0000000000000 --- a/clang/test/CodeGenSPIRV/spirv-host-adaptation-mangling.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/// 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 >From 83ec61e2385ec752cd076162df9050a22a438086 Mon Sep 17 00:00:00 2001 From: Sindhu Chittireddy <[email protected]> Date: Sun, 12 Jul 2026 14:35:38 -0700 Subject: [PATCH 08/11] Fix formatting. --- clang/lib/Basic/Targets/SPIR.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 2dcf07f187e85..7834f963f30f3 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -288,8 +288,7 @@ class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; } else { - assert(PointerWidth == 32 && - "32-bit SPIR target requires a 32-bit host"); + assert(PointerWidth == 32 && "32-bit SPIR target requires a 32-bit host"); } // SPIR32 has support for atomic ops if atomic extension is enabled. // Take the maximum because it's possible the Host supports wider types. @@ -313,8 +312,7 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo { SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; } else { - assert(PointerWidth == 64 && - "64-bit SPIR target requires a 64-bit host"); + assert(PointerWidth == 64 && "64-bit SPIR target requires a 64-bit host"); } // SPIR64 has support for atomic ops if atomic extension is enabled. // Take the maximum because it's possible the Host supports wider types. >From 8d67c8655367d9f01301466e13a9c6732c867bf9 Mon Sep 17 00:00:00 2001 From: Sindhu Chittireddy <[email protected]> Date: Sun, 12 Jul 2026 14:39:20 -0700 Subject: [PATCH 09/11] Move "protected" to its original location --- clang/lib/Basic/Targets/SPIR.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 7834f963f30f3..8ccc371bb429b 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()) && >From 43ed9349be94791b5545d630f5fc3c0bff8a36e6 Mon Sep 17 00:00:00 2001 From: Sindhu Chittireddy <[email protected]> Date: Sun, 12 Jul 2026 14:55:40 -0700 Subject: [PATCH 10/11] Undo mistake - restore "protected" --- clang/lib/Basic/Targets/SPIR.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 8ccc371bb429b..7834f963f30f3 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()) && >From 16d102f87bc0bd8e805fb6f6d8540bee7163dc28 Mon Sep 17 00:00:00 2001 From: Sindhu Chittireddy <[email protected]> Date: Sun, 12 Jul 2026 21:37:02 -0700 Subject: [PATCH 11/11] Fix conditional --- clang/lib/Basic/Targets/SPIR.h | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 7834f963f30f3..f0d40b72226a5 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -283,12 +283,10 @@ class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { : SPIRTargetInfo(Triple, Opts) { assert(Triple.getArch() == llvm::Triple::spir && "Invalid architecture for 32-bit SPIR."); - if (!HostTarget) { - PointerWidth = PointerAlign = 32; + PointerWidth = PointerAlign = 32; + if (!HostTarget || HostTarget->getPointerWidth(LangAS::Default) != 32) { SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; - } else { - assert(PointerWidth == 32 && "32-bit SPIR target requires a 32-bit host"); } // SPIR32 has support for atomic ops if atomic extension is enabled. // Take the maximum because it's possible the Host supports wider types. @@ -307,12 +305,10 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo { : SPIRTargetInfo(Triple, Opts) { assert(Triple.getArch() == llvm::Triple::spir64 && "Invalid architecture for 64-bit SPIR."); - if (!HostTarget) { - PointerWidth = PointerAlign = 64; + PointerWidth = PointerAlign = 64; + if (!HostTarget || HostTarget->getPointerWidth(LangAS::Default) != 64) { SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; - } else { - assert(PointerWidth == 64 && "64-bit SPIR target requires a 64-bit host"); } // SPIR64 has support for atomic ops if atomic extension is enabled. // Take the maximum because it's possible the Host supports wider types. @@ -401,13 +397,10 @@ class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo { "32-bit 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"); - if (!HostTarget) { - PointerWidth = PointerAlign = 32; + PointerWidth = PointerAlign = 32; + if (!HostTarget || HostTarget->getPointerWidth(LangAS::Default) != 32) { SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; - } else { - assert(PointerWidth == 32 && - "32-bit SPIR-V target requires a 32-bit host"); } MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64); resetDataLayout(); @@ -429,13 +422,10 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo { "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"); - if (!HostTarget) { - PointerWidth = PointerAlign = 64; + PointerWidth = PointerAlign = 64; + if (!HostTarget || HostTarget->getPointerWidth(LangAS::Default) != 64) { SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; - } else { - assert(PointerWidth == 64 && - "64-bit SPIR-V target requires a 64-bit host"); } MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64); resetDataLayout(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
