[clang] 61b13e0 - [ClangOffloadBundler] fix unbundling archive (#84195)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 7 06:26:21 PST 2024
Author: Yaxun (Sam) Liu
Date: 2024-03-07T09:26:16-05:00
New Revision: 61b13e0dfe1b476d9bf0fe477983be8471cfd26b
URL: https://github.com/llvm/llvm-project/commit/61b13e0dfe1b476d9bf0fe477983be8471cfd26b
DIFF: https://github.com/llvm/llvm-project/commit/61b13e0dfe1b476d9bf0fe477983be8471cfd26b.diff
LOG: [ClangOffloadBundler] fix unbundling archive (#84195)
When unbundling an archive, need to save the content of each object file
to a temporary file before passing it to llvm-objcopy, instead of
passing the original input archive file to llvm-objcopy.
Also allows extracting host bundles for archives.
Fixes: https://github.com/llvm/llvm-project/issues/83509
Added:
Modified:
clang/lib/Driver/OffloadBundler.cpp
clang/test/Driver/clang-offload-bundler.c
Removed:
################################################################################
diff --git a/clang/lib/Driver/OffloadBundler.cpp b/clang/lib/Driver/OffloadBundler.cpp
index 99a34d25cfcd56..f9eadfaec88dec 100644
--- a/clang/lib/Driver/OffloadBundler.cpp
+++ b/clang/lib/Driver/OffloadBundler.cpp
@@ -590,7 +590,8 @@ class ObjectFileHandler final : public FileHandler {
// Copy fat object contents to the output when extracting host bundle.
std::string ModifiedContent;
if (Content.size() == 1u && Content.front() == 0) {
- auto HostBundleOrErr = getHostBundle();
+ auto HostBundleOrErr = getHostBundle(
+ StringRef(Input.getBufferStart(), Input.getBufferSize()));
if (!HostBundleOrErr)
return HostBundleOrErr.takeError();
@@ -700,7 +701,7 @@ class ObjectFileHandler final : public FileHandler {
return Error::success();
}
- Expected<std::string> getHostBundle() {
+ Expected<std::string> getHostBundle(StringRef Input) {
TempFileHandlerRAII TempFiles;
auto ModifiedObjPathOrErr = TempFiles.Create(std::nullopt);
@@ -715,7 +716,24 @@ class ObjectFileHandler final : public FileHandler {
ObjcopyArgs.push_back("--regex");
ObjcopyArgs.push_back("--remove-section=__CLANG_OFFLOAD_BUNDLE__.*");
ObjcopyArgs.push_back("--");
- ObjcopyArgs.push_back(BundlerConfig.InputFileNames.front());
+
+ StringRef ObjcopyInputFileName;
+ // When unbundling an archive, the content of each object file in the
+ // archive is passed to this function by parameter Input, which is
diff erent
+ // from the content of the original input archive file, therefore it needs
+ // to be saved to a temporary file before passed to llvm-objcopy. Otherwise,
+ // Input is the same as the content of the original input file, therefore
+ // temporary file is not needed.
+ if (StringRef(BundlerConfig.FilesType).starts_with("a")) {
+ auto InputFileOrErr =
+ TempFiles.Create(ArrayRef<char>(Input.data(), Input.size()));
+ if (!InputFileOrErr)
+ return InputFileOrErr.takeError();
+ ObjcopyInputFileName = *InputFileOrErr;
+ } else
+ ObjcopyInputFileName = BundlerConfig.InputFileNames.front();
+
+ ObjcopyArgs.push_back(ObjcopyInputFileName);
ObjcopyArgs.push_back(ModifiedObjPath);
if (Error Err = executeObjcopy(BundlerConfig.ObjcopyPath, ObjcopyArgs))
@@ -1628,10 +1646,8 @@ Error OffloadBundler::UnbundleArchive() {
while (!CodeObject.empty()) {
SmallVector<StringRef> CompatibleTargets;
auto CodeObjectInfo = OffloadTargetInfo(CodeObject, BundlerConfig);
- if (CodeObjectInfo.hasHostKind()) {
- // Do nothing, we don't extract host code yet.
- } else if (getCompatibleOffloadTargets(CodeObjectInfo, CompatibleTargets,
- BundlerConfig)) {
+ if (getCompatibleOffloadTargets(CodeObjectInfo, CompatibleTargets,
+ BundlerConfig)) {
std::string BundleData;
raw_string_ostream DataStream(BundleData);
if (Error Err = FileHandler->ReadBundle(DataStream, CodeObjectBuffer))
diff --git a/clang/test/Driver/clang-offload-bundler.c b/clang/test/Driver/clang-offload-bundler.c
index 9d8b81ee9806ee..f3cd2493e05277 100644
--- a/clang/test/Driver/clang-offload-bundler.c
+++ b/clang/test/Driver/clang-offload-bundler.c
@@ -13,6 +13,19 @@
// RUN: obj2yaml %t.o > %t.o.yaml
// RUN: %clang -O0 -target %itanium_abi_triple %s -emit-ast -o %t.ast
+// RUN: echo 'void a() {}' >%t.a.cpp
+// RUN: echo 'void b() {}' >%t.b.cpp
+// RUN: %clang -target %itanium_abi_triple %t.a.cpp -c -o %t.a.o
+// RUN: %clang -target %itanium_abi_triple %t.b.cpp -c -o %t.b.o
+//
+// Remove .llvm_addrsig section since its offset changes after llvm-objcopy
+// removes clang-offload-bundler sections, therefore not good for comparison.
+//
+// RUN: llvm-objcopy --remove-section=.llvm_addrsig %t.a.o
+// RUN: llvm-objcopy --remove-section=.llvm_addrsig %t.b.o
+// RUN: obj2yaml %t.a.o > %t.a.yaml
+// RUN: obj2yaml %t.b.o > %t.b.yaml
+
//
// Generate an empty file to help with the checks of empty files.
//
@@ -414,6 +427,25 @@
// HIP-AR-906-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906
// HIP-AR-906-DAG: hip_bundle2-hip-amdgcn-amd-amdhsa--gfx906
+//
+// Check unbundling archive for host target
+//
+// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,hip-amdgcn-amd-amdhsa--gfx900 \
+// RUN: -input=%t.a.o -input=%t.tgt1 -output=%t.a.bundled.o
+// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,hip-amdgcn-amd-amdhsa--gfx900 \
+// RUN: -input=%t.b.o -input=%t.tgt1 -output=%t.b.bundled.o
+// RUN: rm -f %t.bundled.a
+// RUN: llvm-ar cr %t.bundled.a %t.a.bundled.o %t.b.bundled.o
+// RUN: cp %t.bundled.a %t.bundled.a.bak
+// RUN: clang-offload-bundler -unbundle --targets=host-%itanium_abi_triple -type=a -input=%t.bundled.a -output=%t.host.a
+// RUN: rm -f *%itanium_abi_triple*.a.bundled.o *%itanium_abi_triple*.b.bundled.o
+// RUN: llvm-ar -x %t.host.a
+// RUN:
diff %t.bundled.a %t.bundled.a.bak
+// RUN: obj2yaml *%itanium_abi_triple*.a.bundled.o > %t.a.unbundled.yaml
+// RUN:
diff %t.a.unbundled.yaml %t.a.yaml
+// RUN: obj2yaml *%itanium_abi_triple*.b.bundled.o > %t.b.unbundled.yaml
+// RUN:
diff %t.b.unbundled.yaml %t.b.yaml
+//
// Check clang-offload-bundler reporting an error when trying to unbundle an archive but
// the input file is not an archive.
//
More information about the cfe-commits
mailing list