-
Notifications
You must be signed in to change notification settings - Fork 13.7k
[LinkerWrapper] Make -Xoffload-linker
match -Xlinker
semantics
#101032
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: Joseph Huber (jhuber6) ChangesSummary: Full diff: https://github.com/llvm/llvm-project/pull/101032.diff 5 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 6790079ccd26a..843d68c85bc59 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -9155,7 +9155,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
// If we disable the GPU C library support it needs to be forwarded to the
// link job.
if (!Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, true))
- CmdArgs.push_back("--device-linker=-nolibc");
+ CmdArgs.push_back("--device-compiler=-nolibc");
// Add the linker arguments to be forwarded by the wrapper.
CmdArgs.push_back(Args.MakeArgString(Twine("--linker-path=") +
diff --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c
index f165a410c1929..99cfdb9ebfc7c 100644
--- a/clang/test/Driver/linker-wrapper.c
+++ b/clang/test/Driver/linker-wrapper.c
@@ -129,14 +129,14 @@ __attribute__((visibility("protected"), used)) int x;
// RUN: -fembed-offload-object=%t.out
// RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \
// RUN: --linker-path=/usr/bin/ld --device-linker=foo=bar --device-linker=a \
-// RUN: --device-linker=nvptx64-nvidia-cuda=b \
+// RUN: --device-linker=nvptx64-nvidia-cuda=b --device-compiler=foo\
// RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=LINKER-ARGS
-// LINKER-ARGS: clang{{.*}}--target=amdgcn-amd-amdhsa{{.*}}foo=bar{{.*}}a
-// LINKER-ARGS: clang{{.*}}--target=nvptx64-nvidia-cuda{{.*}}foo=bar{{.*}}a b
+// LINKER-ARGS: clang{{.*}}--target=amdgcn-amd-amdhsa{{.*}}-Xlinker foo=bar{{.*}}-Xlinker a{{.*}}foo
+// LINKER-ARGS: clang{{.*}}--target=nvptx64-nvidia-cuda{{.*}}-Xlinker foo=bar{{.*}}-Xlinker a -Xlinker b{{.*}}foo
-// RUN: not clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu -ldummy \
-// RUN: --linker-path=/usr/bin/ld --device-linker=a --device-linker=nvptx64-nvidia-cuda=b \
+// RUN: not clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \
+// RUN: -ldummy --linker-path=/usr/bin/ld \
// RUN: -o a.out 2>&1 | FileCheck %s --check-prefix=MISSING-LIBRARY
// MISSING-LIBRARY: error: unable to find library -ldummy
diff --git a/clang/test/Driver/openmp-offload-gpu.c b/clang/test/Driver/openmp-offload-gpu.c
index 0314f28f38a43..ef6cbdded6a6f 100644
--- a/clang/test/Driver/openmp-offload-gpu.c
+++ b/clang/test/Driver/openmp-offload-gpu.c
@@ -377,4 +377,4 @@
// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \
// RUN: --offload-arch=sm_52 -nogpulibc -nogpuinc %s 2>&1 \
// RUN: | FileCheck --check-prefix=LIBC-GPU %s
-// LIBC-GPU: clang-linker-wrapper{{.*}}"--device-linker=-nolibc"
+// LIBC-GPU: clang-linker-wrapper{{.*}}"--device-compiler=-nolibc"
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 2db7b6ac823ec..a7a7b9634605e 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -599,6 +599,8 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args) {
std::back_inserter(CmdArgs));
for (StringRef Arg : Args.getAllArgValues(OPT_linker_arg_EQ))
+ CmdArgs.append({"-Xlinker", Args.MakeArgString(Arg)});
+ for (StringRef Arg : Args.getAllArgValues(OPT_compiler_arg_EQ))
CmdArgs.push_back(Args.MakeArgString(Arg));
for (StringRef Arg : Args.getAllArgValues(OPT_builtin_bitcode_EQ)) {
@@ -1236,6 +1238,23 @@ DerivedArgList getLinkerArgs(ArrayRef<OffloadFile> Input,
Args.MakeArgString(Value));
}
+ // Forward '-Xoffload-compiler' options to the appropriate backend.
+ for (StringRef Arg : Args.getAllArgValues(OPT_device_compiler_args_EQ)) {
+ auto [Triple, Value] = Arg.split('=');
+ llvm::Triple TT(Triple);
+ // If this isn't a recognized triple then it's an `arg=value` option.
+ if (TT.getArch() <= Triple::ArchType::UnknownArch ||
+ TT.getArch() > Triple::ArchType::LastArchType)
+ DAL.AddJoinedArg(nullptr, Tbl.getOption(OPT_compiler_arg_EQ),
+ Args.MakeArgString(Arg));
+ else if (Value.empty())
+ DAL.AddJoinedArg(nullptr, Tbl.getOption(OPT_compiler_arg_EQ),
+ Args.MakeArgString(Triple));
+ else if (Triple == DAL.getLastArgValue(OPT_triple_EQ))
+ DAL.AddJoinedArg(nullptr, Tbl.getOption(OPT_compiler_arg_EQ),
+ Args.MakeArgString(Value));
+ }
+
return DAL;
}
diff --git a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
index a87d5ec8aa9b3..2a29bcacf428a 100644
--- a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
+++ b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
@@ -32,6 +32,9 @@ def builtin_bitcode_EQ : Joined<["--"], "builtin-bitcode=">,
def device_linker_args_EQ : Joined<["--"], "device-linker=">,
Flags<[WrapperOnlyOption]>, MetaVarName<"<value> or <triple>=<value>">,
HelpText<"Arguments to pass to the device linker invocation">;
+def device_compiler_args_EQ : Joined<["--"], "device-compiler=">,
+ Flags<[WrapperOnlyOption]>, MetaVarName<"<value> or <triple>=<value>">,
+ HelpText<"Arguments to pass to the device linker invocation">;
def clang_backend : Flag<["--"], "clang-backend">,
Flags<[WrapperOnlyOption]>,
HelpText<"Run the backend using clang rather than the LTO backend">;
@@ -91,6 +94,9 @@ def whole_program : Flag<["--"], "whole-program">,
def linker_arg_EQ : Joined<["--"], "linker-arg=">,
Flags<[DeviceOnlyOption, HelpHidden]>,
HelpText<"An extra argument to be passed to the linker">;
+def compiler_arg_EQ : Joined<["--"], "compiler-arg=">,
+ Flags<[DeviceOnlyOption, HelpHidden]>,
+ HelpText<"An extra argument to be passed to the compiler">;
// Arguments for the LLVM backend.
def mllvm : Separate<["-"], "mllvm">, Flags<[WrapperOnlyOption]>,
|
if (TT.getArch() <= Triple::ArchType::UnknownArch || | ||
TT.getArch() > Triple::ArchType::LastArchType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd expect Triple to have an isvalid or operator bool or something instead of needing to do this range check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could probably use Triple::parseArch(Str) == Triple::ArchType::UnknownArch)
instead, I think that's as close as we have.
Summary: `-Xlinker` is supposed to pass options to the linker, while `-Xoffload-linker` instead passes it to the `clang` job. This is unintuitive and results in unnecessarily complex command lines. Because passing it to the clang job is still useful, I've added `-device-compiler`. This changes the behavior of the flag, but I think it should be fine in this case since it's likely rarely used and has a direct replacement.
Co-authored-by: Joel E. Denny <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have some sort of documentation where this change of behavior needs to be communicated?
Could probably specify it more in the docs. |
Summary:
-Xlinker
is supposed to pass options to the linker, while-Xoffload-linker
instead passes it to theclang
job. This isunintuitive and results in unnecessarily complex command lines. Because
passing it to the clang job is still useful, I've added
-device-compiler
. This changes the behavior of the flag, but I thinkit should be fine in this case since it's likely rarely used and has a
direct replacement.