https://github.com/pvelesko updated https://github.com/llvm/llvm-project/pull/183991
>From d6d8da8c9604c754b4e217e97e7d51e33a7b6e22 Mon Sep 17 00:00:00 2001 From: Paulius Velesko <[email protected]> Date: Sun, 1 Mar 2026 10:59:45 +0200 Subject: [PATCH 1/6] CGCUDANV, HIPUtility: Use Mach-O segment,section format for HIP on macOS --- clang/lib/CodeGen/CGCUDANV.cpp | 10 +++++++--- clang/lib/Driver/ToolChains/HIPUtility.cpp | 7 +++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index e04da90b3cbf6..f08040d1d3d15 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -817,10 +817,14 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() { llvm::Constant *FatBinStr; unsigned FatMagic; if (IsHIP) { - FatbinConstantName = ".hip_fatbin"; - FatbinSectionName = ".hipFatBinSegment"; + // On macOS (Mach-O), section names must be in "segment,section" format. + FatbinConstantName = + CGM.getTriple().isMacOSX() ? "__HIP,__hip_fatbin" : ".hip_fatbin"; + FatbinSectionName = + CGM.getTriple().isMacOSX() ? "__HIP,__fatbin" : ".hipFatBinSegment"; - ModuleIDSectionName = "__hip_module_id"; + ModuleIDSectionName = + CGM.getTriple().isMacOSX() ? "__HIP,__module_id" : "__hip_module_id"; ModuleIDPrefix = "__hip_"; if (CudaGpuBinary) { diff --git a/clang/lib/Driver/ToolChains/HIPUtility.cpp b/clang/lib/Driver/ToolChains/HIPUtility.cpp index 1fcb36cc3a390..c1ca3d5df2a7e 100644 --- a/clang/lib/Driver/ToolChains/HIPUtility.cpp +++ b/clang/lib/Driver/ToolChains/HIPUtility.cpp @@ -430,9 +430,12 @@ void HIP::constructGenerateObjFileFromHIPFatBinary( } if (FoundPrimaryHipFatbinSymbol) { // Define the first fatbin symbol - if (HostTriple.isWindowsMSVCEnvironment()) + if (HostTriple.isWindowsMSVCEnvironment()) { ObjStream << " .section .hip_fatbin,\"dw\"\n"; - else { + } else if (HostTriple.isMacOSX()) { + // Mach-O requires "segment,section" format + ObjStream << " .section __HIP,__hip_fatbin\n"; + } else { ObjStream << " .protected " << PrimaryHipFatbinSymbol << "\n"; ObjStream << " .type " << PrimaryHipFatbinSymbol << ",@object\n"; ObjStream << " .section .hip_fatbin,\"a\",@progbits\n"; >From 0c7474494e4a58d15d25483dc2db5ec5c2cfa929 Mon Sep 17 00:00:00 2001 From: Paulius Velesko <[email protected]> Date: Sun, 1 Mar 2026 10:59:49 +0200 Subject: [PATCH 2/6] Darwin: Guard HIP/CUDA offloading paths against uninitialized target --- clang/lib/Driver/ToolChains/Darwin.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index aec1ad7d2f155..c46e4dc84b092 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1244,6 +1244,11 @@ void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const { CC1Args.push_back("-Werror=undef-prefix"); // For modern targets, promote certain warnings to errors. + // Guard against uninitialized target (e.g. when Darwin is used as host + // toolchain for HIP/CUDA offloading where the target platform may not + // have been fully set up). See Driver.cpp BuildJobsForAction FIXME. + if (!isTargetInitialized()) + return; if (isTargetWatchOSBased() || getTriple().isArch64Bit()) { // Always enable -Wdeprecated-objc-isa-usage and promote it // to an error. @@ -3899,6 +3904,11 @@ void Darwin::addStartObjectFileArgs(const ArgList &Args, } void Darwin::CheckObjCARC() const { + // Guard against uninitialized target (e.g. when Darwin is used as host + // toolchain for HIP/CUDA offloading). See Driver.cpp BuildJobsForAction + // FIXME. + if (!isTargetInitialized()) + return; if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetXROS() || (isTargetMacOSBased() && !isMacosxVersionLT(10, 6))) return; @@ -3918,6 +3928,11 @@ SanitizerMask Darwin::getSupportedSanitizers() const { Res |= SanitizerKind::FuzzerNoLink; Res |= SanitizerKind::ObjCCast; + // Guard against uninitialized target (e.g. when Darwin is used as host + // toolchain for HIP/CUDA offloading). Return base sanitizers only. + // See Driver.cpp BuildJobsForAction FIXME. + if (!isTargetInitialized()) + return Res; // Prior to 10.9, macOS shipped a version of the C++ standard library without // C++11 support. The same is true of iOS prior to version 5. These OS'es are // incompatible with -fsanitize=vptr. >From 8f3ccbbe9c0f74ecc9f3ded378656fa786531711 Mon Sep 17 00:00:00 2001 From: Paulius Velesko <[email protected]> Date: Sun, 1 Mar 2026 10:59:56 +0200 Subject: [PATCH 3/6] HIPSPV: Do not delegate addClangTargetOptions to host on macOS Host Darwin flags like -faligned-alloc-unavailable break SPIR-V device compilation; SPIR-V device code does not share host stdlib limitations. --- clang/lib/Driver/ToolChains/HIPSPV.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/HIPSPV.cpp b/clang/lib/Driver/ToolChains/HIPSPV.cpp index 8bdb7ab042b2b..c9be378eb5b32 100644 --- a/clang/lib/Driver/ToolChains/HIPSPV.cpp +++ b/clang/lib/Driver/ToolChains/HIPSPV.cpp @@ -159,7 +159,11 @@ void HIPSPVToolChain::addClangTargetOptions( return; } - HostTC->addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind); + // NOTE: Unlike other HIP toolchains, we do NOT delegate to + // HostTC->addClangTargetOptions() here. On macOS (Darwin), the host toolchain + // adds flags like -faligned-alloc-unavailable that are specific to macOS + // libc++ and break SPIR-V device compilation. SPIR-V device code doesn't + // have the same stdlib limitations as the host. assert(DeviceOffloadingKind == Action::OFK_HIP && "Only HIP offloading kinds are supported for GPUs."); >From 04bdc428409063f7b9e64418213ba6c76482710c Mon Sep 17 00:00:00 2001 From: Paulius Velesko <[email protected]> Date: Sun, 1 Mar 2026 17:00:00 +0200 Subject: [PATCH 4/6] [Driver][Darwin] Add ensureTargetInitialized() for lazy target init from triple When Darwin is used as a host toolchain for device offloading (e.g. HIP/CUDA), TranslateArgs may not run before methods that query the target platform, leaving TargetInitialized false and triggering asserts. Add ensureTargetInitialized() which infers the platform and version from the triple, and call it from ComputeEffectiveClangTriple, addClangWarningOptions, CheckObjCARC, and getSupportedSanitizers instead of the previous isTargetInitialized() bail-out guards. --- clang/lib/Driver/ToolChains/Darwin.cpp | 63 +++++++++++++++++++++----- clang/lib/Driver/ToolChains/Darwin.h | 6 +++ 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index c46e4dc84b092..29efb8ea6080d 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1136,6 +1136,50 @@ VersionTuple MachO::getLinkerVersion(const llvm::opt::ArgList &Args) const { Darwin::~Darwin() {} +void Darwin::ensureTargetInitialized() const { + if (TargetInitialized) + return; + + llvm::Triple::OSType OS = getTriple().getOS(); + + DarwinPlatformKind Platform; + switch (OS) { + case llvm::Triple::Darwin: + case llvm::Triple::MacOSX: + Platform = MacOS; + break; + case llvm::Triple::IOS: + Platform = IPhoneOS; + break; + case llvm::Triple::TvOS: + Platform = TvOS; + break; + case llvm::Triple::WatchOS: + Platform = WatchOS; + break; + case llvm::Triple::XROS: + Platform = XROS; + break; + case llvm::Triple::DriverKit: + Platform = DriverKit; + break; + default: + // Unknown platform; leave uninitialized. + return; + } + + DarwinEnvironmentKind Environment = NativeEnvironment; + if (getTriple().isSimulatorEnvironment()) + Environment = Simulator; + else if (getTriple().isMacCatalystEnvironment()) + Environment = MacCatalyst; + + VersionTuple OsVer = getTriple().getOSVersion(); + setTarget(Platform, Environment, OsVer.getMajor(), + OsVer.getMinor().value_or(0), OsVer.getSubminor().value_or(0), + VersionTuple()); +} + AppleMachO::~AppleMachO() {} MachO::~MachO() {} @@ -1177,8 +1221,9 @@ std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args, types::ID InputType) const { llvm::Triple Triple(ComputeLLVMTriple(Args, InputType)); - // If the target isn't initialized (e.g., an unknown Darwin platform, return - // the default triple). + // Lazily initialize the target if needed (e.g. when Darwin is used as + // a host toolchain for device offloading). + ensureTargetInitialized(); if (!isTargetInitialized()) return Triple.getTriple(); @@ -1244,9 +1289,9 @@ void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const { CC1Args.push_back("-Werror=undef-prefix"); // For modern targets, promote certain warnings to errors. - // Guard against uninitialized target (e.g. when Darwin is used as host - // toolchain for HIP/CUDA offloading where the target platform may not - // have been fully set up). See Driver.cpp BuildJobsForAction FIXME. + // Lazily initialize the target if needed (e.g. when Darwin is used as + // a host toolchain for device offloading). + ensureTargetInitialized(); if (!isTargetInitialized()) return; if (isTargetWatchOSBased() || getTriple().isArch64Bit()) { @@ -3904,9 +3949,7 @@ void Darwin::addStartObjectFileArgs(const ArgList &Args, } void Darwin::CheckObjCARC() const { - // Guard against uninitialized target (e.g. when Darwin is used as host - // toolchain for HIP/CUDA offloading). See Driver.cpp BuildJobsForAction - // FIXME. + ensureTargetInitialized(); if (!isTargetInitialized()) return; if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetXROS() || @@ -3928,9 +3971,7 @@ SanitizerMask Darwin::getSupportedSanitizers() const { Res |= SanitizerKind::FuzzerNoLink; Res |= SanitizerKind::ObjCCast; - // Guard against uninitialized target (e.g. when Darwin is used as host - // toolchain for HIP/CUDA offloading). Return base sanitizers only. - // See Driver.cpp BuildJobsForAction FIXME. + ensureTargetInitialized(); if (!isTargetInitialized()) return Res; // Prior to 10.9, macOS shipped a version of the C++ standard library without diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h index 75f1dff46bfa9..89177b0455aca 100644 --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -391,6 +391,12 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO { void VerifyTripleForSDK(const llvm::opt::ArgList &Args, const llvm::Triple Triple) const; +protected: + /// Lazily initialize the target platform from the triple when + /// AddDeploymentTarget has not run yet (e.g. when Darwin is used as + /// a host toolchain for device offloading). + void ensureTargetInitialized() const; + public: Darwin(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); >From bb88e60d4c572e38e1b384a2785973f97689abe7 Mon Sep 17 00:00:00 2001 From: Paulius Velesko <[email protected]> Date: Sun, 1 Mar 2026 17:00:07 +0200 Subject: [PATCH 5/6] [Driver][Darwin] Skip host-stdlib flags when compiling device code When DeviceOffloadKind != OFK_None, return early from Darwin::addClangTargetOptions() after MachO flags. This skips host-specific flags like -faligned-alloc-unavailable and -fno-sized-deallocation that are irrelevant to device compilation and break SPIR-V builds. --- clang/lib/Driver/ToolChains/Darwin.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 29efb8ea6080d..beb200ce10078 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -3426,6 +3426,12 @@ void Darwin::addClangTargetOptions( MachO::addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadKind); + // When compiling device code (e.g. SPIR-V for HIP), skip host-specific + // flags like -faligned-alloc-unavailable and -fno-sized-deallocation + // that depend on the host OS version and are irrelevant to device code. + if (DeviceOffloadKind != Action::OFK_None) + return; + // Pass "-faligned-alloc-unavailable" only when the user hasn't manually // enabled or disabled aligned allocations. if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation, >From 04f230d5d944c02576e115dcaa6ee625f4252133 Mon Sep 17 00:00:00 2001 From: Paulius Velesko <[email protected]> Date: Sun, 1 Mar 2026 17:00:12 +0200 Subject: [PATCH 6/6] [Driver][HIPSPV] Restore HostTC::addClangTargetOptions delegation Now that Darwin skips host-stdlib flags for device offloading, it is safe for HIPSPV to delegate to HostTC->addClangTargetOptions() like other HIP toolchains do. --- clang/lib/Driver/ToolChains/HIPSPV.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/clang/lib/Driver/ToolChains/HIPSPV.cpp b/clang/lib/Driver/ToolChains/HIPSPV.cpp index c9be378eb5b32..8bdb7ab042b2b 100644 --- a/clang/lib/Driver/ToolChains/HIPSPV.cpp +++ b/clang/lib/Driver/ToolChains/HIPSPV.cpp @@ -159,11 +159,7 @@ void HIPSPVToolChain::addClangTargetOptions( return; } - // NOTE: Unlike other HIP toolchains, we do NOT delegate to - // HostTC->addClangTargetOptions() here. On macOS (Darwin), the host toolchain - // adds flags like -faligned-alloc-unavailable that are specific to macOS - // libc++ and break SPIR-V device compilation. SPIR-V device code doesn't - // have the same stdlib limitations as the host. + HostTC->addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind); assert(DeviceOffloadingKind == Action::OFK_HIP && "Only HIP offloading kinds are supported for GPUs."); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
