@@ -5024,15 +5024,24 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
50245024 // Compiling HIP in device-only non-RDC mode requires linking each action
50255025 // individually.
50265026 for (Action *&A : DeviceActions) {
5027- // Special handling for the HIP SPIR-V toolchain because it doesn't use
5028- // the SPIR-V backend yet doesn't report the output as an object.
50295027 bool IsAMDGCNSPIRV = A->getOffloadingToolChain () &&
50305028 A->getOffloadingToolChain ()->getTriple ().getOS () ==
50315029 llvm::Triple::OSType::AMDHSA &&
50325030 A->getOffloadingToolChain ()->getTriple ().isSPIRV ();
5031+ bool UseSPIRVBackend = Args.hasFlag (options::OPT_use_spirv_backend,
5032+ options::OPT_no_use_spirv_backend,
5033+ /* Default=*/ false );
5034+
5035+ // Special handling for the HIP SPIR-V toolchain in device-only.
5036+ // The translator path has a linking step, whereas the SPIR-V backend path
5037+ // does not to avoid any external dependency such as spirv-link. The
5038+ // linking step is skipped for the SPIR-V backend path.
5039+ bool IsAMDGCNSPIRVWithBackend = IsAMDGCNSPIRV && UseSPIRVBackend;
5040+
50335041 if ((A->getType () != types::TY_Object && !IsAMDGCNSPIRV &&
50345042 A->getType () != types::TY_LTO_BC) ||
5035- HIPRelocatableObj || !HIPNoRDC || !offloadDeviceOnly ())
5043+ HIPRelocatableObj || !HIPNoRDC || !offloadDeviceOnly () ||
5044+ (IsAMDGCNSPIRVWithBackend && offloadDeviceOnly ()))
50365045 continue ;
50375046 ActionList LinkerInput = {A};
50385047 A = C.MakeAction <LinkJobAction>(LinkerInput, types::TY_Image);
@@ -5271,9 +5280,20 @@ Action *Driver::ConstructPhaseAction(
52715280 OffloadingToolChain && OffloadingToolChain->getTriple ().isSPIRV ();
52725281 bool IsOffloadOpenMP = TargetDeviceOffloadKind == Action::OFK_OpenMP;
52735282
5283+ bool IsHIP = TargetDeviceOffloadKind == Action::OFK_HIP;
5284+ bool UseSPIRVBackend = Args.hasFlag (options::OPT_use_spirv_backend,
5285+ options::OPT_no_use_spirv_backend,
5286+ /* Default=*/ false );
5287+ // If offloadDeviceOnly(), we call the SPIRV backend unless LLVM bitcode was
5288+ // requested explicitly or RDC is set. If !offloadDeviceOnly, we emit LLVM
5289+ // bitcode, and clang-linker-wrapper will compile it to SPIRV.
5290+ bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5291+ IsHIP && IsSPIRV && UseSPIRVBackend && offloadDeviceOnly () && !IsRDC;
5292+
52745293 bool IsLLVMBitcodeOutput =
52755294 IsEmitLLVM || IsOffloadSYCL ||
52765295 ((IsOffloadAMDGPU || IsOffloadHIP) &&
5296+ !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
52775297 ((IsRDC || (IsNewOffloadDriver &&
52785298 (!offloadDeviceOnly () || (IsOffloadHIP && IsSPIRV)))) ||
52795299 IsOffloadOpenMP));
@@ -5290,6 +5310,22 @@ Action *Driver::ConstructPhaseAction(
52905310 : types::TY_LLVM_BC;
52915311 return C.MakeAction <BackendJobAction>(Input, Output);
52925312 }
5313+
5314+ // The SPIRV backend compilation path for HIP must avoid external
5315+ // dependencies. The default compilation path assembles and links its
5316+ // output, but the SPIRV assembler and linker are external tools. This code
5317+ // ensures the backend emits binary SPIRV directly to bypass those steps and
5318+ // avoid failures. Without -save-temps, the compiler may already skip
5319+ // assembling and linking. With -save-temps, these steps must be explicitly
5320+ // disabled, as done here. We also force skipping these steps regardless of
5321+ // -save-temps to avoid relying on optimizations (unless -S is set).
5322+ bool IsBinarySPIRVOutput =
5323+ UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg (options::OPT_S);
5324+ if (IsBinarySPIRVOutput) {
5325+ // The current HIP bundling expects the type to be types::TY_Image
5326+ return C.MakeAction <BackendJobAction>(Input, types::TY_Image);
5327+ }
5328+
52935329 return C.MakeAction <BackendJobAction>(Input, types::TY_PP_Asm);
52945330 }
52955331 case phases::Assemble:
0 commit comments