[Mlir-commits] [mlir] [MLIR] Add a BlobAttr interface for attribute to wrap arbitrary content and use it as linkLibs for ModuleToObject (PR #120116)
Mehdi Amini
llvmlistbot at llvm.org
Mon Dec 16 13:02:16 PST 2024
================
@@ -215,3 +218,72 @@ TEST_F(MLIRTargetLLVMNVVM,
isaResult.clear();
}
}
+
+// Test linking LLVM IR from a resource attribute.
+TEST_F(MLIRTargetLLVMNVVM, SKIP_WITHOUT_NVPTX(LinkedLLVMIRResource)) {
+ MLIRContext context(registry);
+ std::string moduleStr = R"mlir(
+ gpu.module @nvvm_test {
+ llvm.func @bar()
+ llvm.func @nvvm_kernel(%arg0: f32) attributes {gpu.kernel, nvvm.kernel} {
+ llvm.call @bar() : () -> ()
+ llvm.return
+ }
+ }
+ )mlir";
+ // Provide the library to link as a serialized bitcode blob.
+ SmallVector<char> bitcodeToLink;
+ {
+ std::string linkedLib = R"llvm(
+ define void @bar() {
+ ret void
+ }
+ )llvm";
+ llvm::SMDiagnostic err;
+ llvm::MemoryBufferRef buffer(linkedLib, "linkedLib");
+ llvm::LLVMContext llvmCtx;
+ std::unique_ptr<llvm::Module> module = llvm::parseIR(buffer, err, llvmCtx);
+ ASSERT_TRUE(module) << " Can't parse IR: " << err.getMessage();
+ {
+ llvm::raw_svector_ostream os(bitcodeToLink);
+ WriteBitcodeToFile(*module, os);
+ }
+ }
+
+ OwningOpRef<ModuleOp> module =
+ parseSourceString<ModuleOp>(moduleStr, &context);
+ ASSERT_TRUE(!!module);
+ Builder builder(&context);
+
+ NVVM::NVVMTargetAttr target = NVVM::NVVMTargetAttr::get(&context);
+ auto serializer = dyn_cast<gpu::TargetAttrInterface>(target);
+
+ // Hook to intercept the LLVM IR after linking external libs.
+ std::string linkedLLVMIR;
+ auto linkedCallback = [&linkedLLVMIR](llvm::Module &module) {
+ llvm::raw_string_ostream ros(linkedLLVMIR);
+ module.print(ros, nullptr);
+ };
+
+ // Store the bitcode as a DenseI8ArrayAttr.
+ SmallVector<Attribute> librariesToLink;
+ librariesToLink.push_back(DenseI8ArrayAttr::get(
+ &context,
+ ArrayRef<int8_t>((int8_t *)bitcodeToLink.data(), bitcodeToLink.size())));
+ gpu::TargetOptions options(
+ {}, librariesToLink, {},
+ mlir::gpu::TargetOptions::getDefaultCompilationTarget(), {}, {},
+ linkedCallback);
+ for (auto gpuModule : (*module).getBody()->getOps<gpu::GPUModuleOp>()) {
+ std::optional<SmallVector<char, 0>> object =
+ serializer.serializeToObject(gpuModule, options);
+
+ // Verify that we correctly linked in the library: the external call is
+ // replaced by the definition.
+ ASSERT_TRUE(!linkedLLVMIR.empty());
+ ASSERT_TRUE(
+ StringRef(linkedLLVMIR).contains("define internal void @bar() {"));
----------------
joker-eph wrote:
True, but isn't this on the same level as all the FileCheck CHECK in LLVM?
https://github.com/llvm/llvm-project/pull/120116
More information about the Mlir-commits
mailing list