diff options
author | Yaxun (Sam) Liu <yaxun.liu@amd.com> | 2025-07-09 08:53:10 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-09 08:53:10 -0400 |
commit | beea2a941470368a87b1816e455b1db366c1bbb9 (patch) | |
tree | 27495310517cfe9c2a1a5b40b02acdae8e24cece /clang/lib/Basic | |
parent | ab187bbd3a5c64451846aa3480f271a93dfba760 (diff) | |
download | llvm-beea2a941470368a87b1816e455b1db366c1bbb9.zip llvm-beea2a941470368a87b1816e455b1db366c1bbb9.tar.gz llvm-beea2a941470368a87b1816e455b1db366c1bbb9.tar.bz2 |
[Clang] Respect MS layout attributes during CUDA/HIP device compilation (#146620)
This patch fixes an issue where Microsoft-specific layout attributes,
such as __declspec(empty_bases), were ignored during CUDA/HIP device
compilation on a Windows host. This caused a critical memory layout
mismatch between host and device objects, breaking libraries that rely
on these attributes for ABI compatibility.
The fix introduces a centralized hasMicrosoftRecordLayout() check within
the TargetInfo class. This check is aware of the auxiliary (host) target
and is set during TargetInfo::adjust if the host uses a Microsoft ABI.
The empty_bases, layout_version, and msvc::no_unique_address attributes
now use this centralized flag, ensuring device code respects them and
maintains layout consistency with the host.
Fixes: https://github.com/llvm/llvm-project/issues/146047
Diffstat (limited to 'clang/lib/Basic')
-rw-r--r-- | clang/lib/Basic/TargetInfo.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Basic/Targets/AMDGPU.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Basic/Targets/AMDGPU.h | 3 | ||||
-rw-r--r-- | clang/lib/Basic/Targets/DirectX.h | 5 | ||||
-rw-r--r-- | clang/lib/Basic/Targets/PPC.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Basic/Targets/PPC.h | 3 | ||||
-rw-r--r-- | clang/lib/Basic/Targets/SPIR.h | 15 | ||||
-rw-r--r-- | clang/lib/Basic/Targets/WebAssembly.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Basic/Targets/WebAssembly.h | 3 | ||||
-rw-r--r-- | clang/lib/Basic/Targets/X86.h | 10 |
10 files changed, 41 insertions, 23 deletions
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 9429a31..09b6a1f 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -176,6 +176,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { ? TargetCXXABI::Microsoft : TargetCXXABI::GenericItanium); + HasMicrosoftRecordLayout = TheCXXABI.isMicrosoft(); + // Default to an empty address space map. AddrSpaceMap = &DefaultAddrSpaceMap; UseAddrSpaceMapMangling = false; @@ -410,7 +412,8 @@ bool TargetInfo::isTypeSigned(IntType T) { /// Apply changes to the target information with respect to certain /// language options which change the target configuration and adjust /// the language based on the target options where applicable. -void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { +void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) { if (Opts.NoBitFieldTypeAlign) UseBitFieldTypeAlignment = false; @@ -550,6 +553,10 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { if (Opts.FakeAddressSpaceMap) AddrSpaceMap = &FakeAddrSpaceMap; + + // Check if it's CUDA device compilation; ensure layout consistency with host. + if (Opts.CUDA && Opts.CUDAIsDevice && Aux && !HasMicrosoftRecordLayout) + HasMicrosoftRecordLayout = Aux->getCXXABI().isMicrosoft(); } bool TargetInfo::initFeatureMap( diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 8d5489b..cebcfa3 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -271,8 +271,9 @@ AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple, HalfArgsAndReturns = true; } -void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { - TargetInfo::adjust(Diags, Opts); +void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) { + TargetInfo::adjust(Diags, Opts, Aux); // ToDo: There are still a few places using default address space as private // address space in OpenCL, which needs to be cleaned up, then the references // to OpenCL can be removed from the following line. diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h index 1358abb..8b7fab3 100644 --- a/clang/lib/Basic/Targets/AMDGPU.h +++ b/clang/lib/Basic/Targets/AMDGPU.h @@ -89,7 +89,8 @@ public: void setAddressSpaceMap(bool DefaultIsPrivate); - void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override; + void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) override; uint64_t getPointerWidthV(LangAS AS) const override { if (isR600(getTriple())) diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h index 1729a01..17240cf 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -95,8 +95,9 @@ public: return TargetInfo::VoidPtrBuiltinVaList; } - void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override { - TargetInfo::adjust(Diags, Opts); + void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) override { + TargetInfo::adjust(Diags, Opts, Aux); // The static values this addresses do not apply outside of the same thread // This protection is neither available nor needed Opts.ThreadsafeStatics = false; diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 05a5dc2..ef18354 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -758,10 +758,11 @@ void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { llvm::PPC::fillValidCPUList(Values); } -void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { +void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) { if (HasAltivec) Opts.AltiVec = 1; - TargetInfo::adjust(Diags, Opts); + TargetInfo::adjust(Diags, Opts, Aux); if (LongDoubleFormat != &llvm::APFloat::IEEEdouble()) LongDoubleFormat = Opts.PPCIEEELongDouble ? &llvm::APFloat::IEEEquad() diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 17057ce..9f3a4cd 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -88,7 +88,8 @@ public: } // Set the language option for altivec based on our value. - void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override; + void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) override; // Note: GCC recognizes the following additional cpus: // 401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801, diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index b416a01..1abf798 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -205,8 +205,9 @@ public: AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap; } - void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override { - TargetInfo::adjust(Diags, Opts); + void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) override { + TargetInfo::adjust(Diags, Opts, Aux); // FIXME: SYCL specification considers unannotated pointers and references // to be pointing to the generic address space. See section 5.9.3 of // SYCL 2020 specification. @@ -383,8 +384,9 @@ public: std::optional<LangAS> getConstantAddressSpace() const override { return ConstantAS; } - void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override { - BaseSPIRVTargetInfo::adjust(Diags, Opts); + void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) override { + BaseSPIRVTargetInfo::adjust(Diags, Opts, Aux); // opencl_constant will map to UniformConstant in SPIR-V if (Opts.OpenCL) ConstantAS = LangAS::opencl_constant; @@ -446,8 +448,9 @@ public: void setAuxTarget(const TargetInfo *Aux) override; - void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override { - TargetInfo::adjust(Diags, Opts); + void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) override { + TargetInfo::adjust(Diags, Opts, Aux); } bool hasInt128Type() const override { return TargetInfo::hasInt128Type(); } diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp index f19c57f..af25d25 100644 --- a/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/clang/lib/Basic/Targets/WebAssembly.cpp @@ -372,9 +372,9 @@ WebAssemblyTargetInfo::getTargetBuiltins() const { return {{&BuiltinStrings, BuiltinInfos}}; } -void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags, - LangOptions &Opts) { - TargetInfo::adjust(Diags, Opts); +void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) { + TargetInfo::adjust(Diags, Opts, Aux); // Turn off POSIXThreads and ThreadModel so that we don't predefine _REENTRANT // or __STDCPP_THREADS__ if we will eventually end up stripping atomics // because they are unsupported. diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index d5aee5c..57b366c 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -176,7 +176,8 @@ private: bool hasProtectedVisibility() const override { return false; } - void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override; + void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) override; }; class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index ecb31ff..ebc59c9 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -441,8 +441,9 @@ public: uint64_t getPointerAlignV(LangAS AddrSpace) const override { return getPointerWidthV(AddrSpace); } - void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override { - TargetInfo::adjust(Diags, Opts); + void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) override { + TargetInfo::adjust(Diags, Opts, Aux); IsOpenCL = Opts.OpenCL; } @@ -839,8 +840,9 @@ public: return llvm::IntegerType::MAX_INT_BITS; } - void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override { - TargetInfo::adjust(Diags, Opts); + void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, + const TargetInfo *Aux) override { + TargetInfo::adjust(Diags, Opts, Aux); IsOpenCL = Opts.OpenCL; } |