diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 319f8d5e78dc7..15b81a8f94adc 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -12229,22 +12229,15 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(Twine("-sycl-dump-device-code=") + DumpDir)); } - auto appendOption = [](SmallString<128> &OptString, StringRef AddOpt) { - if (!OptString.empty()) - OptString += " "; - OptString += AddOpt.str(); - }; - // --sycl-post-link-options="options" provides a string of options to be - // passed along to the sycl-post-link tool during device link. - // -Xdevice-post-link is processed separately later. - SmallString<128> PostLinkOptString; + // --sycl-post-link-options="options" provides options to be passed along to + // the sycl-post-link tool during device link. Each token is forwarded as + // its own occurrence so that values are not re-split on spaces in the + // clang-linker-wrapper. -Xdevice-post-link is processed separately later. ArgStringList PostLinkArgs; getNonTripleBasedSYCLPostLinkOpts(getToolChain(), JA, Args, PostLinkArgs); for (const auto &A : PostLinkArgs) - appendOption(PostLinkOptString, A); - if (!PostLinkOptString.empty()) CmdArgs.push_back( - Args.MakeArgString("--sycl-post-link-options=" + PostLinkOptString)); + Args.MakeArgString(Twine("--sycl-post-link-options=") + A)); if (Args.hasArg(options::OPT_fsycl_remove_unused_external_funcs)) CmdArgs.push_back( @@ -12263,15 +12256,14 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back( Args.MakeArgString("-no-sycl-add-default-spec-consts-image")); - // --llvm-spirv-options="options" provides a string of options to be passed - // along to the llvm-spirv (translation) step during device link. - // -Xspirv-translator is processed separately later. - SmallString<128> OptString; + // --llvm-spirv-options="options" provides options to be passed along to the + // llvm-spirv (translation) step during device link. Each token is forwarded + // as its own occurrence so that values are not re-split on spaces in the + // clang-linker-wrapper. -Xspirv-translator is processed separately later. ArgStringList TranslatorArgs; getNonTripleBasedSPIRVTransOpts(C, Args, TranslatorArgs); for (const auto &A : TranslatorArgs) - appendOption(OptString, A); - CmdArgs.push_back(Args.MakeArgString("--llvm-spirv-options=" + OptString)); + CmdArgs.push_back(Args.MakeArgString(Twine("--llvm-spirv-options=") + A)); if (C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()) CmdArgs.push_back("-sycl-is-windows-msvc-env"); @@ -12354,43 +12346,34 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, ":" + TC->getTripleString() + "=" + A)); BuildArgs.clear(); - SmallString<128> PerTargetPostLinkOptString; SYCLTC.TranslateTargetOpt( TC->getTriple(), Args, BuildArgs, options::OPT_Xdevice_post_link, options::OPT_Xdevice_post_link_EQ, /*Device=*/StringRef()); for (const auto &A : BuildArgs) - appendOption(PerTargetPostLinkOptString, A); - if (!PerTargetPostLinkOptString.empty()) - CmdArgs.push_back(Args.MakeArgString( - "--sycl-post-link-options=" + - Action::GetOffloadKindName(Action::OFK_SYCL) + ":" + - TC->getTripleString() + "=" + PerTargetPostLinkOptString)); + CmdArgs.push_back( + Args.MakeArgString("--sycl-post-link-options=" + + Action::GetOffloadKindName(Action::OFK_SYCL) + + ":" + TC->getTripleString() + "=" + A)); BuildArgs.clear(); - SmallString<128> TransOptString; SYCLTC.TranslateTargetOpt( TC->getTriple(), Args, BuildArgs, options::OPT_Xspirv_translator, options::OPT_Xspirv_translator_EQ, /*Device=*/StringRef()); for (const auto &A : BuildArgs) - appendOption(TransOptString, A); - if (!TransOptString.empty()) - CmdArgs.push_back(Args.MakeArgString( - "--llvm-spirv-options=" + - Action::GetOffloadKindName(Action::OFK_SYCL) + ":" + - TC->getTripleString() + "=" + TransOptString)); + CmdArgs.push_back( + Args.MakeArgString("--llvm-spirv-options=" + + Action::GetOffloadKindName(Action::OFK_SYCL) + + ":" + TC->getTripleString() + "=" + A)); BuildArgs.clear(); - SmallString<128> SpirvToIrOptString; SYCLTC.TranslateTargetOpt( TC->getTriple(), Args, BuildArgs, options::OPT_Xspirv_to_ir_wrapper, options::OPT_Xspirv_to_ir_wrapper_EQ, /*Device=*/StringRef()); for (const auto &A : BuildArgs) - appendOption(SpirvToIrOptString, A); - if (!SpirvToIrOptString.empty()) - CmdArgs.push_back(Args.MakeArgString( - "--spirv-to-ir-wrapper-options=" + - Action::GetOffloadKindName(Action::OFK_SYCL) + ":" + - TC->getTripleString() + "=" + SpirvToIrOptString)); + CmdArgs.push_back( + Args.MakeArgString("--spirv-to-ir-wrapper-options=" + + Action::GetOffloadKindName(Action::OFK_SYCL) + + ":" + TC->getTripleString() + "=" + A)); } // Add option to enable creating of the .syclbin file. diff --git a/clang/test/Driver/sycl-device-post-link-opt.cpp b/clang/test/Driver/sycl-device-post-link-opt.cpp index 3d9dab412a40e..cd42a8787b18b 100644 --- a/clang/test/Driver/sycl-device-post-link-opt.cpp +++ b/clang/test/Driver/sycl-device-post-link-opt.cpp @@ -11,8 +11,19 @@ // RUN: %clangxx -fsycl --offload-new-driver --sysroot=%S/Inputs/SYCL -fsycl-targets=spir64,spir64_gen -Xdevice-post-link=spir64_gen "foo" -Xdevice-post-link=spir64 "bar" -### %s 2>&1 | \ // RUN: FileCheck %s -check-prefix CHECK-MULTIPLE-TARGET --implicit-check-not 'sycl-post-link{{.*}} "foo" "bar"' +// Each token is forwarded as its own --sycl-post-link-options occurrence. +// RUN: %clangxx -fsycl --offload-new-driver --sysroot=%S/Inputs/SYCL -Xdevice-post-link "foo bar" -### %s 2>&1 | \ +// RUN: FileCheck %s -check-prefix CHECK-MULTIPLE-TOKENS + +// RUN: %clangxx -fsycl --offload-new-driver --sysroot=%S/Inputs/SYCL -Xdevice-post-link '"foo bar"' -### %s 2>&1 | \ +// RUN: FileCheck %s -check-prefix CHECK-SPACE + // CHECK-SINGLE-TARGET: clang-linker-wrapper{{.*}} {{.*}}--sycl-post-link-options={{.*}}foo{{.*}} // CHECK-SINGLE-TARGET-UNUSED: argument unused during compilation: '-Xdevice-post-link=spir64_gen foo' // CHECK-MULTIPLE-TARGET: clang-linker-wrapper{{.*}} {{.*}}"--sycl-post-link-options=sycl:spir64-unknown-unknown=bar"{{.*}}"--sycl-post-link-options=sycl:spir64_gen-unknown-unknown=foo" + +// CHECK-MULTIPLE-TOKENS: clang-linker-wrapper{{.*}} "--sycl-post-link-options=sycl:spir64-unknown-unknown=foo"{{.*}}"--sycl-post-link-options=sycl:spir64-unknown-unknown=bar" + +// CHECK-SPACE: clang-linker-wrapper{{.*}} "--sycl-post-link-options=sycl:spir64-unknown-unknown=foo bar" diff --git a/clang/test/Driver/sycl-linker-wrapper-image.cpp b/clang/test/Driver/sycl-linker-wrapper-image.cpp index d698e08600266..29acb190421f6 100644 --- a/clang/test/Driver/sycl-linker-wrapper-image.cpp +++ b/clang/test/Driver/sycl-linker-wrapper-image.cpp @@ -15,7 +15,7 @@ // //// RUN: clang-linker-wrapper --print-wrapped-module --host-triple=x86_64-unknown-linux-gnu \ // RUN: --bitcode-library=spir64-unknown-unknown=%t.devicelib.bc \ -// RUN: -sycl-post-link-options="-split=auto -symbols -properties" %t.o -o %t.out 2>&1 --linker-path="/usr/bin/ld" | FileCheck %s +// RUN: -sycl-post-link-options="-split=auto" -sycl-post-link-options="-symbols" -sycl-post-link-options="-properties" %t.o -o %t.out 2>&1 --linker-path="/usr/bin/ld" | FileCheck %s template __attribute__((sycl_kernel)) void kernel(const Func &func) { diff --git a/clang/test/Driver/sycl-offload-new-driver.cpp b/clang/test/Driver/sycl-offload-new-driver.cpp index 518f79530a45f..c823bd6ab6484 100644 --- a/clang/test/Driver/sycl-offload-new-driver.cpp +++ b/clang/test/Driver/sycl-offload-new-driver.cpp @@ -52,7 +52,7 @@ // RUN: %clangxx --target=x86_64-unknown-linux-gnu -fsycl --offload-new-driver --sysroot=%S/Inputs/SYCL \ // RUN: -Xdevice-post-link -post-link-opt -### %s 2>&1 \ // RUN: | FileCheck -check-prefix WRAPPER_OPTIONS_POSTLINK %s -// WRAPPER_OPTIONS_POSTLINK: clang-linker-wrapper{{.*}} "--sycl-post-link-options=-O2 -device-globals"{{.*}} "--sycl-post-link-options=sycl:spir64-unknown-unknown=-post-link-opt" +// WRAPPER_OPTIONS_POSTLINK: clang-linker-wrapper{{.*}} "--sycl-post-link-options=-O2"{{.*}} "--sycl-post-link-options=-device-globals"{{.*}} "--sycl-post-link-options=sycl:spir64-unknown-unknown=-post-link-opt" // -fsycl-device-only behavior // RUN: %clangxx --target=x86_64-unknown-linux-gnu -fsycl --offload-new-driver --sysroot=%S/Inputs/SYCL \ diff --git a/clang/test/Driver/sycl-spirv-metadata.cpp b/clang/test/Driver/sycl-spirv-metadata.cpp index 9fe018bff8a48..2d83e52ff41d7 100644 --- a/clang/test/Driver/sycl-spirv-metadata.cpp +++ b/clang/test/Driver/sycl-spirv-metadata.cpp @@ -8,5 +8,5 @@ // RUN: %clangxx -fsycl --offload-new-driver -### %tfoo.o 2>&1 | \ // RUN: FileCheck -check-prefix CHECK-WITHOUT %s -// CHECK-WITH: clang-linker-wrapper{{.*}} "--llvm-spirv-options={{.*}} --spirv-preserve-auxdata +// CHECK-WITH: clang-linker-wrapper{{.*}} "--llvm-spirv-options=--spirv-preserve-auxdata // CHECK-WITHOUT-NOT: --spirv-preserve-auxdata diff --git a/clang/test/Driver/sycl-spirv-opt.cpp b/clang/test/Driver/sycl-spirv-opt.cpp index 187d142185c70..7d89f9c9fa829 100644 --- a/clang/test/Driver/sycl-spirv-opt.cpp +++ b/clang/test/Driver/sycl-spirv-opt.cpp @@ -11,6 +11,15 @@ // RUN: %clangxx -fsycl -fsycl-targets=spir64,spir64_gen --offload-new-driver --sysroot=%S/Inputs/SYCL -Xspirv-translator=spir64_gen "foo" -Xspirv-translator=spir64 "bar" -### %s 2>&1 | \ // RUN: FileCheck %s -check-prefix CHECK-MULTIPLE-TARGET +// Each token is forwarded as its own --llvm-spirv-options occurrence. +// RUN: %clangxx -fsycl --offload-new-driver --sysroot=%S/Inputs/SYCL -Xspirv-translator "foo bar" -### %s 2>&1 | \ +// RUN: FileCheck %s -check-prefix CHECK-MULTIPLE-TOKENS + +// RUN: %clangxx -fsycl --offload-new-driver --sysroot=%S/Inputs/SYCL -Xspirv-translator '"foo bar"' -### %s 2>&1 | \ +// RUN: FileCheck %s -check-prefix CHECK-SPACE + // CHECK-SINGLE-TARGET: clang-linker-wrapper{{.*}} "--llvm-spirv-options=sycl:spir64-unknown-unknown=foo{{.*}} // CHECK-SINGLE-TARGET-UNUSED: argument unused during compilation: '-Xspirv-translator=spir64_gen foo' // CHECK-MULTIPLE-TARGET: clang-linker-wrapper{{.*}} "--llvm-spirv-options=sycl:spir64-unknown-unknown=bar"{{.*}}"--llvm-spirv-options=sycl:spir64_gen-unknown-unknown=foo" +// CHECK-MULTIPLE-TOKENS: clang-linker-wrapper{{.*}} "--llvm-spirv-options=sycl:spir64-unknown-unknown=foo"{{.*}}"--llvm-spirv-options=sycl:spir64-unknown-unknown=bar" +// CHECK-SPACE: clang-linker-wrapper{{.*}} "--llvm-spirv-options=sycl:spir64-unknown-unknown=foo bar" diff --git a/clang/test/Driver/sycl-spirv-to-ir-opt.cpp b/clang/test/Driver/sycl-spirv-to-ir-opt.cpp index e78e1188be6f3..f476d14f9ad22 100644 --- a/clang/test/Driver/sycl-spirv-to-ir-opt.cpp +++ b/clang/test/Driver/sycl-spirv-to-ir-opt.cpp @@ -11,6 +11,15 @@ // RUN: %clangxx -fsycl -fsycl-targets=spir64,spir64_gen --offload-new-driver --sysroot=%S/Inputs/SYCL -Xspirv-to-ir-wrapper=spir64_gen "foo" -Xspirv-to-ir-wrapper=spir64 "bar" -### %s 2>&1 | \ // RUN: FileCheck %s -check-prefix CHECK-MULTIPLE-TARGET +// Each token is forwarded as its own --spirv-to-ir-wrapper-options occurrence. +// RUN: %clangxx -fsycl --offload-new-driver --sysroot=%S/Inputs/SYCL -Xspirv-to-ir-wrapper "foo bar" -### %s 2>&1 | \ +// RUN: FileCheck %s -check-prefix CHECK-MULTIPLE-TOKENS + +// RUN: %clangxx -fsycl --offload-new-driver --sysroot=%S/Inputs/SYCL -Xspirv-to-ir-wrapper '"foo bar"' -### %s 2>&1 | \ +// RUN: FileCheck %s -check-prefix CHECK-SPACE + // CHECK-SINGLE-TARGET: clang-linker-wrapper{{.*}} "--spirv-to-ir-wrapper-options=sycl:spir64-unknown-unknown=foo{{.*}} // CHECK-SINGLE-TARGET-UNUSED: argument unused during compilation: '-Xspirv-to-ir-wrapper=spir64_gen foo' // CHECK-MULTIPLE-TARGET: clang-linker-wrapper{{.*}} "--spirv-to-ir-wrapper-options=sycl:spir64-unknown-unknown=bar"{{.*}}"--spirv-to-ir-wrapper-options=sycl:spir64_gen-unknown-unknown=foo" +// CHECK-MULTIPLE-TOKENS: clang-linker-wrapper{{.*}} "--spirv-to-ir-wrapper-options=sycl:spir64-unknown-unknown=foo"{{.*}}"--spirv-to-ir-wrapper-options=sycl:spir64-unknown-unknown=bar" +// CHECK-SPACE: clang-linker-wrapper{{.*}} "--spirv-to-ir-wrapper-options=sycl:spir64-unknown-unknown=foo bar" diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index e8ddb7f05c897..0afa376d4cb05 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -622,10 +622,8 @@ static Expected convertSPIRVToIR(StringRef Filename, CmdArgs.push_back("--llvm-spirv-opts"); CmdArgs.push_back("--spirv-preserve-auxdata --spirv-target-env=SPV-IR " "--spirv-builtin-format=global"); - for (const Arg *A : Args.filtered(OPT_spirv_to_ir_wrapper_arg_EQ)) { - StringRef(A->getValue()) - .split(CmdArgs, " ", /* MaxSplit = */ -1, /* KeepEmpty = */ false); - } + for (const Arg *A : Args.filtered(OPT_spirv_to_ir_wrapper_arg_EQ)) + CmdArgs.push_back(A->getValue()); if (Error Err = executeCommands(*SPIRVToIRWrapperPath, CmdArgs)) return std::move(Err); return *TempFileOrErr; @@ -806,10 +804,8 @@ runSYCLPostLinkTool(ArrayRef InputFiles, const ArgList &Args, } } getTripleBasedSYCLPostLinkOpts(Args, CmdArgs, Triple); - for (const Arg *A : Args.filtered(OPT_sycl_post_link_arg_EQ)) { - StringRef(A->getValue()) - .split(CmdArgs, " ", /* MaxSplit = */ -1, /* KeepEmpty = */ false); - } + for (const Arg *A : Args.filtered(OPT_sycl_post_link_arg_EQ)) + CmdArgs.push_back(A->getValue()); CmdArgs.push_back("-o"); CmdArgs.push_back(Args.MakeArgString(OutputPathWithArch)); for (auto &File : InputFiles) @@ -975,10 +971,8 @@ static Expected runLLVMToSPIRVTranslation(StringRef File, CmdArgs.push_back(*LLVMToSPIRVPath); const llvm::Triple Triple(Args.getLastArgValue(OPT_triple_EQ)); getTripleBasedSPIRVTransOpts(Args, CmdArgs, Triple); - for (const Arg *A : Args.filtered(OPT_llvm_spirv_arg_EQ)) { - StringRef(A->getValue()) - .split(CmdArgs, " ", /* MaxSplit = */ -1, /* KeepEmpty = */ false); - } + for (const Arg *A : Args.filtered(OPT_llvm_spirv_arg_EQ)) + CmdArgs.push_back(A->getValue()); CmdArgs.push_back("-o"); // Create a new file to write the translated file to.