-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[MLIR][LLVM] Fix debug intrinsic import #82637
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This revision handles the case that the translation of a scope fails due to cyclic metadata. This mainly affects debug intrinsics that can require a label or variable metadata node as parameter, which may translate to null during import. This commit ensures we drop the intrinsics if they depend on cyclic metadata.
@llvm/pr-subscribers-mlir-llvm @llvm/pr-subscribers-mlir Author: Tobias Gysi (gysit) ChangesThis revision handles the case that the translation of a scope fails due to cyclic metadata. This mainly affects the import of debug intrinsics that indirectly take such a scope as metadata argument (e.g. via local variable or label metadata). This commit ensures we drop intrinsics with such a dependency on cyclic metadata. Full diff: https://github.com/llvm/llvm-project/pull/82637.diff 4 Files Affected:
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index feb3578fe2d496..b88f1186a44b49 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -513,7 +513,11 @@ def LLVM_DbgLabelOp : LLVM_IntrOp<"dbg.label", [], [], [], 0> {
});
}];
let mlirBuilder = [{
- $_op = $_builder.create<$_qualCppClassName>($_location, $_label_attr($label));
+ DILabelAttr labelAttr = $_label_attr($label);
+ // Drop the intrinsic if the label translation fails due to cylic metadata.
+ if (!labelAttr)
+ return success();
+ $_op = $_builder.create<$_qualCppClassName>($_location, labelAttr);
}];
let assemblyFormat = "$label attr-dict";
}
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index 65212952300913..c631617f973544 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -99,21 +99,31 @@ DIFileAttr DebugImporter::translateImpl(llvm::DIFile *node) {
}
DILabelAttr DebugImporter::translateImpl(llvm::DILabel *node) {
- return DILabelAttr::get(context, translate(node->getScope()),
+ // Return nullptr if the scope or type is a cyclic dependency.
+ DIScopeAttr scope = translate(node->getScope());
+ if (node->getScope() && !scope)
+ return nullptr;
+ return DILabelAttr::get(context, scope,
getStringAttrOrNull(node->getRawName()),
translate(node->getFile()), node->getLine());
}
DILexicalBlockAttr DebugImporter::translateImpl(llvm::DILexicalBlock *node) {
- return DILexicalBlockAttr::get(context, translate(node->getScope()),
- translate(node->getFile()), node->getLine(),
- node->getColumn());
+ // Return nullptr if the scope or type is a cyclic dependency.
+ DIScopeAttr scope = translate(node->getScope());
+ if (node->getScope() && !scope)
+ return nullptr;
+ return DILexicalBlockAttr::get(context, scope, translate(node->getFile()),
+ node->getLine(), node->getColumn());
}
DILexicalBlockFileAttr
DebugImporter::translateImpl(llvm::DILexicalBlockFile *node) {
- return DILexicalBlockFileAttr::get(context, translate(node->getScope()),
- translate(node->getFile()),
+ // Return nullptr if the scope or type is a cyclic dependency.
+ DIScopeAttr scope = translate(node->getScope());
+ if (node->getScope() && !scope)
+ return nullptr;
+ return DILexicalBlockFileAttr::get(context, scope, translate(node->getFile()),
node->getDiscriminator());
}
@@ -135,11 +145,14 @@ DebugImporter::translateImpl(llvm::DIGlobalVariable *node) {
}
DILocalVariableAttr DebugImporter::translateImpl(llvm::DILocalVariable *node) {
- return DILocalVariableAttr::get(context, translate(node->getScope()),
- getStringAttrOrNull(node->getRawName()),
- translate(node->getFile()), node->getLine(),
- node->getArg(), node->getAlignInBits(),
- translate(node->getType()));
+ // Return nullptr if the scope or type is a cyclic dependency.
+ DIScopeAttr scope = translate(node->getScope());
+ if (node->getScope() && !scope)
+ return nullptr;
+ return DILocalVariableAttr::get(
+ context, scope, getStringAttrOrNull(node->getRawName()),
+ translate(node->getFile()), node->getLine(), node->getArg(),
+ node->getAlignInBits(), translate(node->getType()));
}
DIScopeAttr DebugImporter::translateImpl(llvm::DIScope *node) {
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 97ccb2b29f3aec..d63ea12ecd49b1 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1966,6 +1966,13 @@ ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
// TODO: find a way to support this case.
if (isMetadataKillLocation(dbgIntr))
return emitUnsupportedWarning();
+ // Drop debug intrinsics if the associated variable information cannot be
+ // translated due to cyclic debug metadata.
+ // TODO: Support cyclic debug metadata.
+ DILocalVariableAttr localVariableAttr =
+ matchLocalVariableAttr(dbgIntr->getArgOperand(1));
+ if (!localVariableAttr)
+ return emitUnsupportedWarning();
FailureOr<Value> argOperand = convertMetadataValue(dbgIntr->getArgOperand(0));
if (failed(argOperand))
return emitError(loc) << "failed to convert a debug intrinsic operand: "
@@ -1991,8 +1998,6 @@ ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
} else {
builder.setInsertionPointAfterValue(*argOperand);
}
- DILocalVariableAttr localVariableAttr =
- matchLocalVariableAttr(dbgIntr->getArgOperand(1));
auto locationExprAttr =
debugImporter->translateExpression(dbgIntr->getExpression());
Operation *op =
diff --git a/mlir/test/Target/LLVMIR/Import/import-failure.ll b/mlir/test/Target/LLVMIR/Import/import-failure.ll
index 09621346656636..9a4e939d106516 100644
--- a/mlir/test/Target/LLVMIR/Import/import-failure.ll
+++ b/mlir/test/Target/LLVMIR/Import/import-failure.ll
@@ -59,13 +59,15 @@ define void @unhandled_intrinsic() gc "example" {
; // -----
+; Check that debug intrinsics with an unsupported argument are dropped.
+
declare void @llvm.dbg.value(metadata, metadata, metadata)
; CHECK: import-failure.ll
-; CHECK-SAME: warning: dropped intrinsic: call void @llvm.dbg.value(metadata !DIArgList(i64 %arg1, i64 undef), metadata !3, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 1, DW_OP_mul, DW_OP_plus, DW_OP_stack_value)), !dbg !5
+; CHECK-SAME: warning: dropped intrinsic: call void @llvm.dbg.value(metadata !DIArgList(i64 %{{.*}}, i64 undef), metadata !3, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 1, DW_OP_mul, DW_OP_plus, DW_OP_stack_value))
; CHECK: import-failure.ll
-; CHECK-SAME: warning: dropped intrinsic: call void @llvm.dbg.value(metadata !6, metadata !3, metadata !DIExpression()), !dbg !5
-define void @dropped_instruction(i64 %arg1) {
+; CHECK-SAME: warning: dropped intrinsic: call void @llvm.dbg.value(metadata !6, metadata !3, metadata !DIExpression())
+define void @unsupported_argument(i64 %arg1) {
call void @llvm.dbg.value(metadata !DIArgList(i64 %arg1, i64 undef), metadata !3, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 1, DW_OP_mul, DW_OP_plus, DW_OP_stack_value)), !dbg !5
call void @llvm.dbg.value(metadata !6, metadata !3, metadata !DIExpression()), !dbg !5
ret void
@@ -83,6 +85,38 @@ define void @dropped_instruction(i64 %arg1) {
; // -----
+; Check that debug intrinsics that depend on cyclic metadata are dropped.
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+; CHECK: import-failure.ll
+; CHECK-SAME: warning: dropped instruction: call void @llvm.dbg.label(metadata !{{.*}})
+; CHECK: import-failure.ll
+; CHECK-SAME: warning: dropped intrinsic: call void @llvm.dbg.value(metadata i64 %{{.*}}, metadata !3, metadata !DIExpression())
+define void @cylic_metadata(i64 %arg1) {
+ call void @llvm.dbg.value(metadata i64 %arg1, metadata !10, metadata !DIExpression()), !dbg !14
+ call void @llvm.dbg.label(metadata !13), !dbg !14
+ ret void
+}
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
+!2 = !DIFile(filename: "import-failure.ll", directory: "/")
+!3 = !DICompositeType(tag: DW_TAG_array_type, size: 42, baseType: !4)
+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !3)
+!5 = distinct !DISubprogram(name: "class_method", scope: !2, file: !2, type: !6, spFlags: DISPFlagDefinition, unit: !1)
+!6 = !DISubroutineType(types: !7)
+!7 = !{!3}
+!10 = !DILocalVariable(scope: !5, name: "arg1", file: !2, line: 1, arg: 1, align: 64);
+!11 = !DILexicalBlock(scope: !5)
+!12 = !DILexicalBlockFile(scope: !11, discriminator: 0)
+!13 = !DILabel(scope: !12, name: "label", file: !2, line: 42)
+!14 = !DILocation(line: 1, column: 2, scope: !5)
+
+; // -----
+
; global_dtors with non-null data fields cannot be represented in MLIR.
; CHECK: <unknown>
; CHECK-SAME: error: unhandled global variable: @llvm.global_dtors
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
This revision handles the case that the translation of a scope fails due to cyclic metadata. This mainly affects the import of debug intrinsics that indirectly take such a scope as metadata argument (e.g. via local variable or label metadata). This commit ensures we drop intrinsics with such a dependency on cyclic metadata.