@@ -4981,15 +4981,24 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
49814981 // Compiling HIP in device-only non-RDC mode requires linking each action
49824982 // individually.
49834983 for (Action *&A : DeviceActions) {
4984- // Special handling for the HIP SPIR-V toolchain because it doesn't use
4985- // the SPIR-V backend yet doesn't report the output as an object.
49864984 bool IsAMDGCNSPIRV = A->getOffloadingToolChain () &&
49874985 A->getOffloadingToolChain ()->getTriple ().getOS () ==
49884986 llvm::Triple::OSType::AMDHSA &&
49894987 A->getOffloadingToolChain ()->getTriple ().isSPIRV ();
4988+ bool UseSPIRVBackend = Args.hasFlag (options::OPT_use_spirv_backend,
4989+ options::OPT_no_use_spirv_backend,
4990+ /* Default=*/ false );
4991+
4992+ // Special handling for the HIP SPIR-V toolchain in device-only.
4993+ // The translator path has a linking step, whereas the SPIR-V backend path
4994+ // does not to avoid any external dependency such as spirv-link. The
4995+ // linking step is skipped for the SPIR-V backend path.
4996+ bool IsAMDGCNSPIRVWithBackend = IsAMDGCNSPIRV && UseSPIRVBackend;
4997+
49904998 if ((A->getType () != types::TY_Object && !IsAMDGCNSPIRV &&
49914999 A->getType () != types::TY_LTO_BC) ||
4992- HIPRelocatableObj || !HIPNoRDC || !offloadDeviceOnly ())
5000+ HIPRelocatableObj || !HIPNoRDC || !offloadDeviceOnly () ||
5001+ (IsAMDGCNSPIRVWithBackend && offloadDeviceOnly ()))
49935002 continue ;
49945003 ActionList LinkerInput = {A};
49955004 A = C.MakeAction <LinkJobAction>(LinkerInput, types::TY_Image);
@@ -5228,9 +5237,20 @@ Action *Driver::ConstructPhaseAction(
52285237 OffloadingToolChain && OffloadingToolChain->getTriple ().isSPIRV ();
52295238 bool IsOffloadOpenMP = TargetDeviceOffloadKind == Action::OFK_OpenMP;
52305239
5240+ bool IsHIP = TargetDeviceOffloadKind == Action::OFK_HIP;
5241+ bool UseSPIRVBackend = Args.hasFlag (options::OPT_use_spirv_backend,
5242+ options::OPT_no_use_spirv_backend,
5243+ /* Default=*/ false );
5244+ // If offloadDeviceOnly(), we call the SPIRV backend unless LLVM bitcode was
5245+ // requested explicitly or RDC is set. If !offloadDeviceOnly, we emit LLVM
5246+ // bitcode, and clang-linker-wrapper will compile it to SPIRV.
5247+ bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5248+ IsHIP && IsSPIRV && UseSPIRVBackend && offloadDeviceOnly () && !IsRDC;
5249+
52315250 bool IsLLVMBitcodeOutput =
52325251 IsEmitLLVM || IsOffloadSYCL ||
52335252 ((IsOffloadAMDGPU || IsOffloadHIP) &&
5253+ !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
52345254 ((IsRDC || (IsNewOffloadDriver &&
52355255 (!offloadDeviceOnly () || (IsOffloadHIP && IsSPIRV)))) ||
52365256 IsOffloadOpenMP));
@@ -5247,6 +5267,22 @@ Action *Driver::ConstructPhaseAction(
52475267 : types::TY_LLVM_BC;
52485268 return C.MakeAction <BackendJobAction>(Input, Output);
52495269 }
5270+
5271+ // The SPIRV backend compilation path for HIP must avoid external
5272+ // dependencies. The default compilation path assembles and links its
5273+ // output, but the SPIRV assembler and linker are external tools. This code
5274+ // ensures the backend emits binary SPIRV directly to bypass those steps and
5275+ // avoid failures. Without -save-temps, the compiler may already skip
5276+ // assembling and linking. With -save-temps, these steps must be explicitly
5277+ // disabled, as done here. We also force skipping these steps regardless of
5278+ // -save-temps to avoid relying on optimizations (unless -S is set).
5279+ bool IsBinarySPIRVOutput =
5280+ UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg (options::OPT_S);
5281+ if (IsBinarySPIRVOutput) {
5282+ // The current HIP bundling expects the type to be types::TY_Image
5283+ return C.MakeAction <BackendJobAction>(Input, types::TY_Image);
5284+ }
5285+
52505286 return C.MakeAction <BackendJobAction>(Input, types::TY_PP_Asm);
52515287 }
52525288 case phases::Assemble:
0 commit comments