[clang] [LinkerWrapper] Forward `-mllvm` and `--offload-opt` arguments to device (PR #100424)
Joseph Huber via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 25 14:00:05 PDT 2024
https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/100424
>From da623e1f8259a42aee469dc99f05e8cd24caf511 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Wed, 24 Jul 2024 11:44:22 -0500
Subject: [PATCH 1/2] [LinkerWrapper] Forward `-mllvm` and `--offload-opt`
arguments to device
Summary:
Previously we could parse these internally as they would be used by the
embedded LTO job. Now, this LTO is passed to the linker utilities which
means these need to be forwarded. So this can now either be done with
`--offload-opt` which works in the clang job, or with `-Xoffload-linker`
manually.
Fixes https://github.com/llvm/llvm-project/issues/100212
---
clang/test/Driver/linker-wrapper-passes.c | 3 ---
clang/test/Driver/linker-wrapper.c | 10 ++++++++++
.../clang-linker-wrapper/ClangLinkerWrapper.cpp | 12 ++++++++++--
.../tools/clang-linker-wrapper/LinkerWrapperOpts.td | 2 +-
4 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/clang/test/Driver/linker-wrapper-passes.c b/clang/test/Driver/linker-wrapper-passes.c
index fb63ef7970ac7..faa6c082ea177 100644
--- a/clang/test/Driver/linker-wrapper-passes.c
+++ b/clang/test/Driver/linker-wrapper-passes.c
@@ -4,9 +4,6 @@
// REQUIRES: x86-registered-target
// REQUIRES: amdgpu-registered-target
-// https://github.com/llvm/llvm-project/issues/100212
-// XFAIL: *
-
// Setup.
// RUN: mkdir -p %t
// RUN: %clang -cc1 -emit-llvm-bc -o %t/host-x86_64-unknown-linux-gnu.bc \
diff --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c
index 342907c1a3390..f165a410c1929 100644
--- a/clang/test/Driver/linker-wrapper.c
+++ b/clang/test/Driver/linker-wrapper.c
@@ -234,3 +234,13 @@ __attribute__((visibility("protected"), used)) int x;
// RUN: | FileCheck %s --check-prefix=OVERRIDE
// OVERRIDE-NOT: clang
// OVERRIDE: /usr/bin/ld
+
+// RUN: clang-offload-packager -o %t.out \
+// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
+// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
+// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run --offload-opt=-pass-remarks=foo \
+// RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=OFFLOAD-OPT
+// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run -mllvm -pass-remarks=foo \
+// RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=OFFLOAD-OPT
+
+// OFFLOAD-OPT: clang{{.*}}-Wl,--plugin-opt=-pass-remarks=foo
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 4bb021eae25a8..2db7b6ac823ec 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -297,7 +297,8 @@ Expected<std::string> findProgram(StringRef Name, ArrayRef<StringRef> Paths) {
/// supported by the toolchain.
bool linkerSupportsLTO(const ArgList &Args) {
llvm::Triple Triple(Args.getLastArgValue(OPT_triple_EQ));
- return Triple.isNVPTX() || Triple.isAMDGPU();
+ return Triple.isNVPTX() || Triple.isAMDGPU() ||
+ Args.getLastArgValue(OPT_linker_path_EQ).ends_with("ld.lld");
}
/// Returns the hashed value for a constant string.
@@ -524,6 +525,13 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args) {
Args.MakeArgString("-" + OptLevel),
};
+ // Forward all of the `--offload-opt` and similar options to the device.
+ if (linkerSupportsLTO(Args)) {
+ for (auto &Arg : Args.filtered(OPT_offload_opt_eq_minus, OPT_mllvm))
+ CmdArgs.push_back(
+ Args.MakeArgString("-Wl,--plugin-opt=" + StringRef(Arg->getValue())));
+ }
+
if (!Triple.isNVPTX())
CmdArgs.push_back("-Wl,--no-undefined");
@@ -1756,7 +1764,7 @@ int main(int Argc, char **Argv) {
for (const opt::Arg *Arg : Args.filtered(OPT_mllvm))
NewArgv.push_back(Arg->getValue());
for (const opt::Arg *Arg : Args.filtered(OPT_offload_opt_eq_minus))
- NewArgv.push_back(Args.MakeArgString(StringRef("-") + Arg->getValue()));
+ NewArgv.push_back(Arg->getValue());
SmallVector<PassPlugin, 1> PluginList;
PassPlugins.setCallback([&](const std::string &PluginPath) {
auto Plugin = PassPlugin::Load(PluginPath);
diff --git a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
index 9c27e588fc4f5..a87d5ec8aa9b3 100644
--- a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
+++ b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
@@ -98,7 +98,7 @@ def mllvm : Separate<["-"], "mllvm">, Flags<[WrapperOnlyOption]>,
HelpText<"Arguments passed to LLVM, including Clang invocations, for which "
"the '-mllvm' prefix is preserved. Use '-mllvm --help' for a list "
"of options.">;
-def offload_opt_eq_minus : Joined<["--", "-"], "offload-opt=-">, Flags<[HelpHidden, WrapperOnlyOption]>,
+def offload_opt_eq_minus : Joined<["--", "-"], "offload-opt=">, Flags<[HelpHidden, WrapperOnlyOption]>,
HelpText<"Options passed to LLVM, not including the Clang invocation. Use "
"'--offload-opt=--help' for a list of options.">;
>From 78667b2fd0d24e2089af55ca757be8a4bf0b063f Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Thu, 25 Jul 2024 15:59:50 -0500
Subject: [PATCH 2/2] Joel changes
---
clang/test/Driver/linker-wrapper-passes.c | 4 +-
.../ClangLinkerWrapper.cpp | 53 +++++++++++++++++--
2 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/clang/test/Driver/linker-wrapper-passes.c b/clang/test/Driver/linker-wrapper-passes.c
index faa6c082ea177..e85ade56c107a 100644
--- a/clang/test/Driver/linker-wrapper-passes.c
+++ b/clang/test/Driver/linker-wrapper-passes.c
@@ -27,6 +27,7 @@
// RUN: --linker-path=/usr/bin/true %t/host-x86_64-unknown-linux-gnu.o \
// RUN: %offload-opt-loadbye --offload-opt=-wave-goodbye \
// RUN: --offload-opt=-passes="function(goodbye),module(inline)" 2>&1 | \
+// RUN: grep -v "warning: argument unused during compilation: '--no-default-config'" | \
// RUN: FileCheck -match-full-lines -check-prefixes=OUT %s
// Check plugin, -p, and remarks.
@@ -38,6 +39,7 @@
// RUN: --offload-opt=-pass-remarks-output=%t/remarks.yml \
// RUN: --offload-opt=-pass-remarks-filter=inline \
// RUN: --offload-opt=-pass-remarks-format=yaml 2>&1 | \
+// RUN: grep -v "warning: argument unused during compilation: '--no-default-config'" | \
// RUN: FileCheck -match-full-lines -check-prefixes=OUT,REM %s
// RUN: FileCheck -input-file=%t/remarks.yml -match-full-lines \
// RUN: -check-prefixes=YML %s
@@ -50,7 +52,7 @@
// OUT-NOT: {{.}}
// OUT: Bye: f
// OUT-NEXT: Bye: test
-// REM-NEXT: remark: {{.*}} 'f' inlined into 'test' {{.*}}
+// REM-NEXT: {{.*}} 'f' inlined into 'test' {{.*}}
// OUT-NOT: {{.}}
// YML-NOT: {{.}}
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 2db7b6ac823ec..dfb72364020fd 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -527,9 +527,56 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args) {
// Forward all of the `--offload-opt` and similar options to the device.
if (linkerSupportsLTO(Args)) {
- for (auto &Arg : Args.filtered(OPT_offload_opt_eq_minus, OPT_mllvm))
- CmdArgs.push_back(
- Args.MakeArgString("-Wl,--plugin-opt=" + StringRef(Arg->getValue())));
+ for (auto &Arg : Args.filtered(OPT_offload_opt_eq_minus, OPT_mllvm)) {
+ StringRef Val = Arg->getValue();
+ // --help documents them with "--" but option parsing accepts them with
+ // "-" too, so either could arrive here.
+ auto consumeOpt = [](StringRef &Val, StringRef Opt) {
+ assert(Opt.starts_with("--"));
+ return Val.consume_front(Opt) || Val.consume_front(Opt.substr(1));
+ };
+ // Use -Xlinker not -Wl, which doesn't treat commas as plain text.
+ if (consumeOpt(Val, "--pass-remarks-with-hotness=")) {
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString("--opt-remarks-with-hotness"));
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString(Val));
+ } else if (consumeOpt(Val, "--pass-remarks-hotness-threshold=")) {
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString("--opt-remarks-hotness-threshold"));
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString(Val));
+ } else if (consumeOpt(Val, "--pass-remarks-output=")) {
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString("--opt-remarks-filename"));
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString(Val));
+ } else if (consumeOpt(Val, "--pass-remarks-filter=")) {
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString("--opt-remarks-passes"));
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString(Val));
+ } else if (consumeOpt(Val, "--pass-remarks-format=")) {
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString("--opt-remarks-format"));
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString(Val));
+ } else if (consumeOpt(Val, "--load-pass-plugin=")) {
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString("--load-pass-plugin=" + Val));
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString("-mllvm=-load=" + Val));
+ } else if (consumeOpt(Val, "--passes=") || Val.consume_front("-p=")) {
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(Args.MakeArgString("--lto-newpm-passes=" + Val));
+ } else {
+ // This is needed for at least -pass-remarks and options defined by any
+ // loaded plugins (e.g., -wave-goodbye defined by Bye.so).
+ CmdArgs.push_back(Args.MakeArgString("-Xlinker"));
+ CmdArgs.push_back(
+ Args.MakeArgString("-mllvm=" + StringRef(Arg->getValue())));
+ }
+ }
}
if (!Triple.isNVPTX())
More information about the cfe-commits
mailing list