diff --git a/clang/test/Frontend/embed-object.c b/clang/test/Frontend/embed-object.c --- a/clang/test/Frontend/embed-object.c +++ b/clang/test/Frontend/embed-object.c @@ -4,3 +4,6 @@ // CHECK: @llvm.compiler.used = appending global [1 x ptr] [ptr @[[OBJECT]]], section "llvm.metadata" void foo(void) {} + +// CHECK: !llvm.embedded.object = !{![[METADATA:[0-9]+]]} +// CHECK: ![[METADATA]] = !{ptr @[[OBJECT]], !".llvm.offloading"} diff --git a/clang/test/Frontend/embed-object.ll b/clang/test/Frontend/embed-object.ll --- a/clang/test/Frontend/embed-object.ll +++ b/clang/test/Frontend/embed-object.ll @@ -13,3 +13,7 @@ define i32 @foo() { ret i32 0 } + +; CHECK: !llvm.embedded.object = !{![[METADATA_1:[0-9]+]], ![[METADATA_2:[0-9]+]]} +; CHECK: ![[METADATA_1]] = !{ptr @[[OBJECT_1]], !".llvm.offloading"} +; CHECK: ![[METADATA_2]] = !{ptr @[[OBJECT_2]], !".llvm.offloading"} diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -366,12 +366,23 @@ return createStringError(inconvertibleErrorCode(), "Failed to create module"); - // Extract offloading data from globals with the `.llvm.offloading` section. - for (GlobalVariable &GV : M->globals()) { - if (!GV.hasSection() || !GV.getSection().equals(OFFLOAD_SECTION_MAGIC_STR)) + // Extract offloading data from globals referenced by the + // `llvm.embedded.object` metadata with the `.llvm.offloading` section. + auto MD = M->getNamedMetadata("llvm.embedded.object"); + for (const MDNode *Op : MD->operands()) { + if (Op->getNumOperands() < 2) continue; - auto *CDS = dyn_cast(GV.getInitializer()); + MDString *SectionID = dyn_cast(Op->getOperand(1)); + if (!SectionID || SectionID->getString() != OFFLOAD_SECTION_MAGIC_STR) + continue; + + GlobalVariable *GV = + mdconst::dyn_extract_or_null(Op->getOperand(0)); + if (!GV) + continue; + + auto *CDS = dyn_cast(GV->getInitializer()); if (!CDS) continue; diff --git a/llvm/include/llvm/Transforms/Utils/ModuleUtils.h b/llvm/include/llvm/Transforms/Utils/ModuleUtils.h --- a/llvm/include/llvm/Transforms/Utils/ModuleUtils.h +++ b/llvm/include/llvm/Transforms/Utils/ModuleUtils.h @@ -109,7 +109,8 @@ std::string getUniqueModuleId(Module *M); /// Embed the memory buffer \p Buf into the module \p M as a global using the -/// specified section name. +/// specified section name. Also provide metadata entry to identify it in the +/// module using the same section name. void embedBufferInModule(Module &M, MemoryBufferRef Buf, StringRef SectionName, Align Alignment = Align(1)); diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp --- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -275,5 +275,12 @@ GV->setSection(SectionName); GV->setAlignment(Alignment); + LLVMContext &Ctx = M.getContext(); + NamedMDNode *MD = M.getOrInsertNamedMetadata("llvm.embedded.object"); + Metadata *MDVals[] = {ConstantAsMetadata::get(GV), + MDString::get(Ctx, SectionName)}; + + MD->addOperand(llvm::MDNode::get(Ctx, MDVals)); + appendToCompilerUsed(M, GV); }