Skip to content

Commit 335d34d

Browse files
authored
[MLIR][LLVM] Fix debug intrinsic import (#82637)
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.
1 parent bbdc62e commit 335d34d

File tree

4 files changed

+73
-17
lines changed

4 files changed

+73
-17
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,11 @@ def LLVM_DbgLabelOp : LLVM_IntrOp<"dbg.label", [], [], [], 0> {
513513
});
514514
}];
515515
let mlirBuilder = [{
516-
$_op = $_builder.create<$_qualCppClassName>($_location, $_label_attr($label));
516+
DILabelAttr labelAttr = $_label_attr($label);
517+
// Drop the intrinsic if the label translation fails due to cylic metadata.
518+
if (!labelAttr)
519+
return success();
520+
$_op = $_builder.create<$_qualCppClassName>($_location, labelAttr);
517521
}];
518522
let assemblyFormat = "$label attr-dict";
519523
}

mlir/lib/Target/LLVMIR/DebugImporter.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,21 +99,31 @@ DIFileAttr DebugImporter::translateImpl(llvm::DIFile *node) {
9999
}
100100

101101
DILabelAttr DebugImporter::translateImpl(llvm::DILabel *node) {
102-
return DILabelAttr::get(context, translate(node->getScope()),
102+
// Return nullptr if the scope or type is a cyclic dependency.
103+
DIScopeAttr scope = translate(node->getScope());
104+
if (node->getScope() && !scope)
105+
return nullptr;
106+
return DILabelAttr::get(context, scope,
103107
getStringAttrOrNull(node->getRawName()),
104108
translate(node->getFile()), node->getLine());
105109
}
106110

107111
DILexicalBlockAttr DebugImporter::translateImpl(llvm::DILexicalBlock *node) {
108-
return DILexicalBlockAttr::get(context, translate(node->getScope()),
109-
translate(node->getFile()), node->getLine(),
110-
node->getColumn());
112+
// Return nullptr if the scope or type is a cyclic dependency.
113+
DIScopeAttr scope = translate(node->getScope());
114+
if (node->getScope() && !scope)
115+
return nullptr;
116+
return DILexicalBlockAttr::get(context, scope, translate(node->getFile()),
117+
node->getLine(), node->getColumn());
111118
}
112119

113120
DILexicalBlockFileAttr
114121
DebugImporter::translateImpl(llvm::DILexicalBlockFile *node) {
115-
return DILexicalBlockFileAttr::get(context, translate(node->getScope()),
116-
translate(node->getFile()),
122+
// Return nullptr if the scope or type is a cyclic dependency.
123+
DIScopeAttr scope = translate(node->getScope());
124+
if (node->getScope() && !scope)
125+
return nullptr;
126+
return DILexicalBlockFileAttr::get(context, scope, translate(node->getFile()),
117127
node->getDiscriminator());
118128
}
119129

@@ -135,11 +145,14 @@ DebugImporter::translateImpl(llvm::DIGlobalVariable *node) {
135145
}
136146

137147
DILocalVariableAttr DebugImporter::translateImpl(llvm::DILocalVariable *node) {
138-
return DILocalVariableAttr::get(context, translate(node->getScope()),
139-
getStringAttrOrNull(node->getRawName()),
140-
translate(node->getFile()), node->getLine(),
141-
node->getArg(), node->getAlignInBits(),
142-
translate(node->getType()));
148+
// Return nullptr if the scope or type is a cyclic dependency.
149+
DIScopeAttr scope = translate(node->getScope());
150+
if (node->getScope() && !scope)
151+
return nullptr;
152+
return DILocalVariableAttr::get(
153+
context, scope, getStringAttrOrNull(node->getRawName()),
154+
translate(node->getFile()), node->getLine(), node->getArg(),
155+
node->getAlignInBits(), translate(node->getType()));
143156
}
144157

145158
DIScopeAttr DebugImporter::translateImpl(llvm::DIScope *node) {

mlir/lib/Target/LLVMIR/ModuleImport.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,6 +1966,13 @@ ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
19661966
// TODO: find a way to support this case.
19671967
if (isMetadataKillLocation(dbgIntr))
19681968
return emitUnsupportedWarning();
1969+
// Drop debug intrinsics if the associated variable information cannot be
1970+
// translated due to cyclic debug metadata.
1971+
// TODO: Support cyclic debug metadata.
1972+
DILocalVariableAttr localVariableAttr =
1973+
matchLocalVariableAttr(dbgIntr->getArgOperand(1));
1974+
if (!localVariableAttr)
1975+
return emitUnsupportedWarning();
19691976
FailureOr<Value> argOperand = convertMetadataValue(dbgIntr->getArgOperand(0));
19701977
if (failed(argOperand))
19711978
return emitError(loc) << "failed to convert a debug intrinsic operand: "
@@ -1991,8 +1998,6 @@ ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
19911998
} else {
19921999
builder.setInsertionPointAfterValue(*argOperand);
19932000
}
1994-
DILocalVariableAttr localVariableAttr =
1995-
matchLocalVariableAttr(dbgIntr->getArgOperand(1));
19962001
auto locationExprAttr =
19972002
debugImporter->translateExpression(dbgIntr->getExpression());
19982003
Operation *op =

mlir/test/Target/LLVMIR/Import/import-failure.ll

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@ define void @unhandled_intrinsic() gc "example" {
5959

6060
; // -----
6161

62+
; Check that debug intrinsics with an unsupported argument are dropped.
63+
6264
declare void @llvm.dbg.value(metadata, metadata, metadata)
6365

6466
; CHECK: import-failure.ll
65-
; 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
67+
; 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))
6668
; CHECK: import-failure.ll
67-
; CHECK-SAME: warning: dropped intrinsic: call void @llvm.dbg.value(metadata !6, metadata !3, metadata !DIExpression()), !dbg !5
68-
define void @dropped_instruction(i64 %arg1) {
69+
; CHECK-SAME: warning: dropped intrinsic: call void @llvm.dbg.value(metadata !6, metadata !3, metadata !DIExpression())
70+
define void @unsupported_argument(i64 %arg1) {
6971
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
7072
call void @llvm.dbg.value(metadata !6, metadata !3, metadata !DIExpression()), !dbg !5
7173
ret void
@@ -83,6 +85,38 @@ define void @dropped_instruction(i64 %arg1) {
8385

8486
; // -----
8587

88+
; Check that debug intrinsics that depend on cyclic metadata are dropped.
89+
90+
declare void @llvm.dbg.value(metadata, metadata, metadata)
91+
92+
; CHECK: import-failure.ll
93+
; CHECK-SAME: warning: dropped instruction: call void @llvm.dbg.label(metadata !{{.*}})
94+
; CHECK: import-failure.ll
95+
; CHECK-SAME: warning: dropped intrinsic: call void @llvm.dbg.value(metadata i64 %{{.*}}, metadata !3, metadata !DIExpression())
96+
define void @cylic_metadata(i64 %arg1) {
97+
call void @llvm.dbg.value(metadata i64 %arg1, metadata !10, metadata !DIExpression()), !dbg !14
98+
call void @llvm.dbg.label(metadata !13), !dbg !14
99+
ret void
100+
}
101+
102+
!llvm.dbg.cu = !{!1}
103+
!llvm.module.flags = !{!0}
104+
!0 = !{i32 2, !"Debug Info Version", i32 3}
105+
!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
106+
!2 = !DIFile(filename: "import-failure.ll", directory: "/")
107+
!3 = !DICompositeType(tag: DW_TAG_array_type, size: 42, baseType: !4)
108+
!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !3)
109+
!5 = distinct !DISubprogram(name: "class_method", scope: !2, file: !2, type: !6, spFlags: DISPFlagDefinition, unit: !1)
110+
!6 = !DISubroutineType(types: !7)
111+
!7 = !{!3}
112+
!10 = !DILocalVariable(scope: !5, name: "arg1", file: !2, line: 1, arg: 1, align: 64);
113+
!11 = !DILexicalBlock(scope: !5)
114+
!12 = !DILexicalBlockFile(scope: !11, discriminator: 0)
115+
!13 = !DILabel(scope: !12, name: "label", file: !2, line: 42)
116+
!14 = !DILocation(line: 1, column: 2, scope: !5)
117+
118+
; // -----
119+
86120
; global_dtors with non-null data fields cannot be represented in MLIR.
87121
; CHECK: <unknown>
88122
; CHECK-SAME: error: unhandled global variable: @llvm.global_dtors

0 commit comments

Comments
 (0)