diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 4fe5f0fd09e15..cb095691dfda1 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -10452,7 +10452,7 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, static_cast(*TC); SYCLTC.AddImpliedTargetArgs(TC->getTriple(), Args, BuildArgs, JA, *HostTC, Arch); - SYCLTC.TranslateBackendTargetArgs(TC->getTriple(), Args, BuildArgs); + SYCLTC.TranslateBackendTargetArgs(TC->getTriple(), Args, BuildArgs, Arch); createArgString("compile-opts="); BuildArgs.clear(); SYCLTC.TranslateLinkerTargetArgs(TC->getTriple(), Args, BuildArgs); @@ -11614,27 +11614,51 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, if (!TC->getTriple().isSPIROrSPIRV()) continue; ArgStringList BuildArgs; - SmallString<128> BackendOptString; + std::vector> BackendOptVec; SmallString<128> LinkOptString; - SYCLTC.TranslateBackendTargetArgs(TC->getTriple(), Args, BuildArgs); - for (const auto &A : BuildArgs) - appendOption(BackendOptString, A); - BuildArgs.clear(); + // Construct backend options for each target passed via -Xsycl-target-backend + // in the form: "-device " + StringRef Device = ""; + for (const Arg *A : Args.filtered(options::OPT_Xsycl_backend_EQ, options::OPT_Xsycl_backend)) { + SmallString<128> BackendArgs; + if(A->getNumValues() > 1) { + Device = SYCL::gen::resolveGenDevice(A->getValue()); + if(Device.empty() && (A->getNumValues() > 1)) + // If target is spir64_gen, the device name needs to be extracted + // from the arguments. + Device = SYCL::gen::extractDeviceFromArg(A->getValue(1)); + else + // If target is intel_gpu_*, "-device " + // is appended to BackendArgs. + appendOption(BackendArgs, "-device " + Device.str()); + } + SYCLTC.TranslateBackendTargetArgs(TC->getTriple(), Args, BuildArgs, Device); + for (const auto &BA : BuildArgs) { + appendOption(BackendArgs, BA); + } + if(!BackendArgs.empty()) { + BackendOptVec.push_back(std::move(BackendArgs)); + } + BuildArgs.clear(); + } + SYCLTC.TranslateLinkerTargetArgs(TC->getTriple(), Args, BuildArgs); for (const auto &A : BuildArgs) { if (TC->getTriple().getSubArch() == llvm::Triple::NoSubArch) appendOption(LinkOptString, A); - else + else { // For AOT, combine the Backend and Linker strings into one. - appendOption(BackendOptString, A); + for (SmallString<128> &BackendArgs : BackendOptVec) + appendOption(BackendArgs, A); + } } - if (!BackendOptString.empty()) { + for (SmallString<128> &BackendArgs : BackendOptVec) { CmdArgs.push_back(Args.MakeArgString( "--device-compiler=" + Action::GetOffloadKindName(Action::OFK_SYCL) + ":" + - TC->getTripleString() + "=" + BackendOptString)); + TC->getTripleString() + "=" + BackendArgs)); } if (!LinkOptString.empty()) { CmdArgs.push_back(Args.MakeArgString( diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp b/clang/lib/Driver/ToolChains/SYCL.cpp index a4db63c4fb52f..0aae858369947 100644 --- a/clang/lib/Driver/ToolChains/SYCL.cpp +++ b/clang/lib/Driver/ToolChains/SYCL.cpp @@ -1083,6 +1083,18 @@ void SYCL::gen::BackendCompiler::ConstructJob(Compilation &C, C.addCommand(std::move(Cmd)); } +// Extracts the device specified after "-device" from the backend +// argument string provided via -Xsycl-target-backend. +StringRef SYCL::gen::extractDeviceFromArg(llvm::StringRef Arg) { + llvm::SmallVector Arglist; + Arg.split(Arglist, ' '); + for (size_t i = 0; i + 1 < Arglist.size(); ++i) { + if (Arglist[i] == "-device") + return Arglist[i + 1]; + } + return ""; +} + StringRef SYCL::gen::resolveGenDevice(StringRef DeviceName) { StringRef Device; Device = @@ -1556,6 +1568,8 @@ void SYCLToolChain::TranslateTargetOpt(const llvm::Triple &Triple, getDriver().getSYCLDeviceTriple(A->getValue(), A); // Passing device args: -X= -opt=val. StringRef GenDevice = SYCL::gen::resolveGenDevice(A->getValue()); + if(GenDevice.empty()) + GenDevice = SYCL::gen::extractDeviceFromArg(A->getValue(1)); bool IsGenTriple = Triple.isSPIR() && Triple.getSubArch() == llvm::Triple::SPIRSubArch_gen; if (IsGenTriple) { @@ -1565,9 +1579,6 @@ void SYCLToolChain::TranslateTargetOpt(const llvm::Triple &Triple, // Triples do not match, but only skip when we know we are not // comparing against intel_gpu_* continue; - if (OptTargetTriple == Triple && !Device.empty()) - // Triples match, but we are expecting a specific device to be set. - continue; } else if (OptTargetTriple != Triple) continue; } else if (!OptNoTriple) @@ -1678,6 +1689,7 @@ void SYCLToolChain::AddImpliedTargetArgs(const llvm::Triple &Triple, } // Check for any -device settings. std::string DevArg; + llvm::errs() << "[DEBUG] device is " << Device << "\n"; if (IsJIT || Device == "pvc" || hasPVCDevice(TargArgs, DevArg)) { // The -device option passed in by the user may not be 'pvc'. Use the // value provided by the user if it was specified. diff --git a/clang/lib/Driver/ToolChains/SYCL.h b/clang/lib/Driver/ToolChains/SYCL.h index c1403ae1d5036..66e5f31f23725 100644 --- a/clang/lib/Driver/ToolChains/SYCL.h +++ b/clang/lib/Driver/ToolChains/SYCL.h @@ -84,6 +84,7 @@ class LLVM_LIBRARY_VISIBILITY BackendCompiler : public Tool { const char *LinkingOutput) const override; }; +StringRef extractDeviceFromArg(StringRef Arg); StringRef resolveGenDevice(StringRef DeviceName); SmallString<64> getGenDeviceMacro(StringRef DeviceName); StringRef getGenGRFFlag(StringRef GRFMode); diff --git a/clang/test/Driver/clang-linker-wrapper.cpp b/clang/test/Driver/clang-linker-wrapper.cpp index 08662ec57d0a2..6abb1a152afee 100644 --- a/clang/test/Driver/clang-linker-wrapper.cpp +++ b/clang/test/Driver/clang-linker-wrapper.cpp @@ -73,9 +73,9 @@ // Check that when "--device-compiler=triple=-device pvc" is specified in clang-linker-wrapper // (happen when AOT device is specified via -Xsycl-target-backend '-device pvc' in clang), -// the target is not passed to sycl-post-link for filtering. +// the target is passed to sycl-post-link for filtering. // RUN: clang-linker-wrapper -sycl-embed-ir -sycl-device-libraries=%t1.devicelib.o -sycl-post-link-options="SYCL_POST_LINK_OPTIONS" -llvm-spirv-options="LLVM_SPIRV_OPTIONS" "--host-triple=x86_64-unknown-linux-gnu" "--device-compiler=spir64_gen-unknown-unknown=-device pvc" "--linker-path=/usr/bin/ld" "--" HOST_LINKER_FLAGS "-dynamic-linker" HOST_DYN_LIB "-o" "a.out" HOST_LIB_PATH HOST_STAT_LIB %t1.o --dry-run 2>&1 | FileCheck -check-prefix=CHK-NO-CMDS-AOT-GEN %s -// CHK-NO-CMDS-AOT-GEN: sycl-post-link{{.*}} SYCL_POST_LINK_OPTIONS -o {{[^,]*}}.table {{.*}}.bc +// CHK-NO-CMDS-AOT-GEN: sycl-post-link{{.*}} SYCL_POST_LINK_OPTIONS -o intel_gpu_pvc,{{.*}}.table {{.*}}.bc /// Check for list of commands for standalone clang-linker-wrapper run for sycl (AOT for Intel CPU) // ------- diff --git a/clang/test/Driver/sycl-offload-new-driver.cpp b/clang/test/Driver/sycl-offload-new-driver.cpp index 0e8b394b1aa3b..1a2a535d5d8f0 100644 --- a/clang/test/Driver/sycl-offload-new-driver.cpp +++ b/clang/test/Driver/sycl-offload-new-driver.cpp @@ -162,6 +162,15 @@ // WRAPPER_OPTIONS_BACKEND_AOT-SAME: "--device-compiler=sycl:spir64_gen-unknown-unknown=-backend-gen-opt" // WRAPPER_OPTIONS_BACKEND_AOT-SAME: "--device-compiler=sycl:spir64_x86_64-unknown-unknown=-backend-cpu-opt" +// Check that AOT backend compiler options passed via +// -Xsycl-target-backend=,