llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-mlir-llvm Author: Akimasa Watanuki (Men-cotton) <details> <summary>Changes</summary> Import global value references inside LLVM metadata operands as LLVM dialect metadata symbol-reference attributes. Add llvm.read_register import coverage for function, global, alias, and nameless-global metadata operands. --- Full diff: https://github.com/llvm/llvm-project/pull/203017.diff 3 Files Affected: - (modified) mlir/lib/Target/LLVMIR/ModuleImport.cpp (+49-12) - (modified) mlir/test/Target/LLVMIR/Import/import-failure.ll (+45) - (modified) mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll (+78-5) ``````````diff diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index 3038a6a2ed986..6cd7490f2e85d 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -150,6 +150,28 @@ static LogicalResult convertInstructionImpl(OpBuilder &odsBuilder, return failure(); } +static FlatSymbolRefAttr getMetadataGlobalValueSymbolRef( + MLIRContext *ctx, LLVMImportInterface &iface, llvm::GlobalValue *global, + llvm::function_ref<FlatSymbolRefAttr(llvm::GlobalVariable *)> + getNamelessGlobalSymbol) { + if (auto *globalVar = dyn_cast<llvm::GlobalVariable>(global)) { + StringRef name = globalVar->getName(); + if (name.empty()) + return getNamelessGlobalSymbol(globalVar); + if (name == getGlobalCtorsVarName() || name == getGlobalDtorsVarName()) + return {}; + } + + if (auto *func = dyn_cast<llvm::Function>(global)) + if (func->isIntrinsic() && + iface.isConvertibleIntrinsic(func->getIntrinsicID())) + return {}; + + if (global->getName().empty()) + return {}; + return FlatSymbolRefAttr::get(ctx, global->getName()); +} + /// Depth-first conversion of the metadata node `md` to the matching LLVM /// dialect metadata attribute. Returns a null attribute for shapes that the /// dialect's metadata-attribute hierarchy does not currently model. `path` @@ -162,23 +184,30 @@ static LogicalResult convertInstructionImpl(OpBuilder &odsBuilder, static Attribute convertMetadataToAttrImpl( MLIRContext *ctx, const llvm::Metadata *md, SmallPtrSetImpl<const llvm::Metadata *> &path, - DenseMap<const llvm::Metadata *, Attribute> &attrMap) { + DenseMap<const llvm::Metadata *, Attribute> &attrMap, + LLVMImportInterface &iface, + llvm::function_ref<FlatSymbolRefAttr(llvm::GlobalVariable *)> + getNamelessGlobalSymbol) { if (!md) return {}; if (auto *mdStr = dyn_cast<llvm::MDString>(md)) return MDStringAttr::get(ctx, StringAttr::get(ctx, mdStr->getString())); if (auto *cam = dyn_cast<llvm::ConstantAsMetadata>(md)) { - auto *ci = dyn_cast<llvm::ConstantInt>(cam->getValue()); + llvm::Constant *constant = cam->getValue(); + if (auto *global = dyn_cast<llvm::GlobalValue>(constant)) + if (FlatSymbolRefAttr symbolRef = getMetadataGlobalValueSymbolRef( + ctx, iface, global, getNamelessGlobalSymbol)) + return MDFuncAttr::get(ctx, symbolRef); + auto *ci = dyn_cast<llvm::ConstantInt>(constant); if (!ci) return {}; auto intType = IntegerType::get(ctx, ci->getBitWidth()); return MDConstantAttr::get(ctx, IntegerAttr::get(intType, ci->getValue())); } if (auto *vam = dyn_cast<llvm::ValueAsMetadata>(md)) { - auto *fn = dyn_cast<llvm::Function>(vam->getValue()); - if (!fn) - return {}; - return MDFuncAttr::get(ctx, FlatSymbolRefAttr::get(ctx, fn->getName())); + if (isa<llvm::GlobalValue>(vam->getValue())) + llvm_unreachable("global values should be ConstantAsMetadata"); + return {}; } if (auto *node = dyn_cast<llvm::MDNode>(md)) { if (Attribute cached = attrMap.lookup(node)) @@ -190,8 +219,8 @@ static Attribute convertMetadataToAttrImpl( SmallVector<Attribute> operands; operands.reserve(node->getNumOperands()); for (const llvm::MDOperand &op : node->operands()) { - Attribute opAttr = - convertMetadataToAttrImpl(ctx, op.get(), path, attrMap); + Attribute opAttr = convertMetadataToAttrImpl( + ctx, op.get(), path, attrMap, iface, getNamelessGlobalSymbol); if (!opAttr) return {}; operands.push_back(opAttr); @@ -208,11 +237,14 @@ static Attribute convertMetadataToAttrImpl( /// attribute. Returns a null attribute for shapes that the dialect's /// metadata-attribute hierarchy does not currently model, including cyclic /// metadata graphs that the immutable metadata attributes cannot express. -static Attribute convertMetadataToAttr(MLIRContext *ctx, - const llvm::Metadata *md) { +static Attribute convertMetadataToAttr( + MLIRContext *ctx, const llvm::Metadata *md, LLVMImportInterface &iface, + llvm::function_ref<FlatSymbolRefAttr(llvm::GlobalVariable *)> + getNamelessGlobalSymbol) { SmallPtrSet<const llvm::Metadata *, 8> path; DenseMap<const llvm::Metadata *, Attribute> attrMap; - return convertMetadataToAttrImpl(ctx, md, path, attrMap); + return convertMetadataToAttrImpl(ctx, md, path, attrMap, iface, + getNamelessGlobalSymbol); } /// Get a topologically sorted list of blocks for the given basic blocks. @@ -1982,7 +2014,12 @@ FailureOr<Value> ModuleImport::convertValue(llvm::Value *value) { // attribute. if (auto *mdAsVal = dyn_cast<llvm::MetadataAsValue>(value)) { llvm::Metadata *md = mdAsVal->getMetadata(); - Attribute mdAttr = convertMetadataToAttr(context, md); + auto getNamelessGlobalSymbol = + [this](llvm::GlobalVariable *globalVar) -> FlatSymbolRefAttr { + return getOrCreateNamelessSymbolName(globalVar); + }; + Attribute mdAttr = + convertMetadataToAttr(context, md, iface, getNamelessGlobalSymbol); if (!mdAttr) return emitError(mlirModule.getLoc()) << "unsupported metadata: " << diagMD(md, llvmModule.get()); diff --git a/mlir/test/Target/LLVMIR/Import/import-failure.ll b/mlir/test/Target/LLVMIR/Import/import-failure.ll index 57c8438bfd362..04c26d571f2e9 100644 --- a/mlir/test/Target/LLVMIR/Import/import-failure.ll +++ b/mlir/test/Target/LLVMIR/Import/import-failure.ll @@ -468,3 +468,48 @@ define i32 @cyclic_metadata_as_value() { } !0 = distinct !{!0} + +; // ----- + +; CHECK: error: unsupported metadata: ptr @llvm.memcpy.p0.p0.i64 +declare i32 @llvm.read_register.i32(metadata) +declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly, ptr noalias readonly, i64, i1 immarg) + +define i32 @skipped_intrinsic_metadata() { + %r = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %r +} + +!0 = !{ptr @llvm.memcpy.p0.p0.i64} + +; // ----- + +; CHECK: error: unsupported metadata: ptr @llvm.global_ctors +declare i32 @llvm.read_register.i32(metadata) +define void @ctor() { + ret void +} [email protected]_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @ctor, ptr null }] + +define i32 @metadata_ref_global_ctors() { + %r = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %r +} + +!0 = !{ptr @llvm.global_ctors} + +; // ----- + +; CHECK: error: unsupported metadata: ptr @llvm.global_dtors +declare i32 @llvm.read_register.i32(metadata) +define void @dtor() { + ret void +} [email protected]_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @dtor, ptr null }] + +define i32 @metadata_ref_global_dtors() { + %r = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %r +} + +!0 = !{ptr @llvm.global_dtors} diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll b/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll index da58d48d995be..14323b49a2d5a 100644 --- a/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll +++ b/mlir/test/Target/LLVMIR/Import/intrinsic-unregistered.ll @@ -11,7 +11,6 @@ define dso_local void @t0(ptr %a) { ; CHECK-LABEL: llvm.func @t0 ; CHECK: llvm.call_intrinsic "llvm.aarch64.ldxr.p0"({{.*}}) : (!llvm.ptr {llvm.elementtype = i8}) -> i64 ; CHECK: llvm.return -; CHECK: } ; // ----- @@ -22,10 +21,9 @@ define dso_local <8 x i8> @t1(<8 x i8> %lhs, <8 x i8> %rhs) { ret <8 x i8> %r } -; CHECK: llvm.func @t1(%[[A0:.*]]: vector<8xi8>, %[[A1:.*]]: vector<8xi8>) -> vector<8xi8> {{.*}} { +; CHECK: llvm.func @t1(%[[A0:.*]]: vector<8xi8>, %[[A1:.*]]: vector<8xi8>) -> vector<8xi8> {{.*}} ; CHECK: %[[R:.*]] = llvm.call_intrinsic "llvm.aarch64.neon.uabd.v8i8"(%[[A0]], %[[A1]]) : (vector<8xi8>, vector<8xi8>) -> vector<8xi8> ; CHECK: llvm.return %[[R]] : vector<8xi8> -; CHECK: } ; // ----- @@ -36,10 +34,9 @@ define dso_local void @t2(<8 x i8> %lhs, <8 x i8> %rhs, ptr %a) { ret void } -; CHECK: llvm.func @t2(%[[A0:.*]]: vector<8xi8>, %[[A1:.*]]: vector<8xi8>, %[[A2:.*]]: !llvm.ptr) {{.*}} { +; CHECK: llvm.func @t2(%[[A0:.*]]: vector<8xi8>, %[[A1:.*]]: vector<8xi8>, %[[A2:.*]]: !llvm.ptr) {{.*}} ; CHECK: llvm.call_intrinsic "llvm.aarch64.neon.st2.v8i8.p0"(%[[A0]], %[[A1]], %[[A2]]) : (vector<8xi8>, vector<8xi8>, !llvm.ptr) -> () ; CHECK: llvm.return -; CHECK: } ; // ----- @@ -115,3 +112,79 @@ define i32 @read_named_register() { } !0 = !{!"sp"} + +; // ----- + +; Function references inside metadata operands should import as metadata +; function-reference attributes. + +declare i32 @llvm.read_register.i32(metadata) +declare void @callee() + +; CHECK-LABEL: llvm.func @read_function_ref_metadata +define i32 @read_function_ref_metadata() { + ; CHECK: %[[MD:.*]] = llvm.mlir.metadata_as_value #llvm.md_func<@callee> + ; CHECK: %[[R:.*]] = llvm.call_intrinsic "llvm.read_register.i32"(%[[MD]]) : (!llvm.metadata) -> i32 + %r = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %r +} + +!0 = !{ptr @callee} + +; // ----- + +; Global variable references inside metadata operands should import as metadata +; symbol-reference attributes. + +declare i32 @llvm.read_register.i32(metadata) +@global = global i32 0 + +; CHECK-LABEL: llvm.func @read_global_ref_metadata +define i32 @read_global_ref_metadata() { + ; CHECK: %[[MD:.*]] = llvm.mlir.metadata_as_value #llvm.md_func<@global> + ; CHECK: %[[R:.*]] = llvm.call_intrinsic "llvm.read_register.i32"(%[[MD]]) : (!llvm.metadata) -> i32 + %r = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %r +} + +!0 = !{ptr @global} + +; // ----- + +; Global alias references inside metadata operands should import as metadata +; symbol-reference attributes. + +declare i32 @llvm.read_register.i32(metadata) +define void @alias_target() { + ret void +} +@alias = alias void (), ptr @alias_target + +; CHECK-LABEL: llvm.func @read_alias_ref_metadata +define i32 @read_alias_ref_metadata() { + ; CHECK: %[[MD:.*]] = llvm.mlir.metadata_as_value #llvm.md_func<@alias> + ; CHECK: %[[R:.*]] = llvm.call_intrinsic "llvm.read_register.i32"(%[[MD]]) : (!llvm.metadata) -> i32 + %r = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %r +} + +!0 = !{ptr @alias} + +; // ----- + +; Nameless global references inside metadata operands should use the imported +; synthetic symbol name. + +declare i32 @llvm.read_register.i32(metadata) +@0 = global i32 0 + +; CHECK: llvm.mlir.global external @[[$GLOBAL:mlir\.llvm\.nameless_global_[0-9]+]](0 : i32) +; CHECK-LABEL: llvm.func @read_nameless_global_ref_metadata +define i32 @read_nameless_global_ref_metadata() { + ; CHECK: %[[MD:.*]] = llvm.mlir.metadata_as_value #llvm.md_func<@[[$GLOBAL]]> + ; CHECK: %[[R:.*]] = llvm.call_intrinsic "llvm.read_register.i32"(%[[MD]]) : (!llvm.metadata) -> i32 + %r = call i32 @llvm.read_register.i32(metadata !0) + ret i32 %r +} + +!0 = !{ptr @0} `````````` </details> https://github.com/llvm/llvm-project/pull/203017 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
