Skip to content

Commit a902ca6

Browse files
authored
[MLIR][LLVM] Infer export location scope from location, if possible (#70465)
This commit changes the debug location exporter to try to infer the locations scope from the MLIR location, if possible. This is necessary when the function containing the operation does not have a DISubprogram attached to it. We observed a roundtrip crash with a case where the the subprogram was missing on a function, but a debug intrinsic referenced a subprogram non-the-less. This lead to a successful import, but the export silently dropped the location, which results in invalid IR.
1 parent 1770a2e commit a902ca6

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

mlir/lib/Target/LLVMIR/DebugTranslation.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ llvm::DILocation *DebugTranslation::translateLoc(Location loc,
286286
llvm::DILocalScope *scope,
287287
llvm::DILocation *inlinedAt) {
288288
// LLVM doesn't have a representation for unknown.
289-
if (!scope || isa<UnknownLoc>(loc))
289+
if (isa<UnknownLoc>(loc))
290290
return nullptr;
291291

292292
// Check for a cached instance.
@@ -301,17 +301,12 @@ llvm::DILocation *DebugTranslation::translateLoc(Location loc,
301301
llvmLoc = translateLoc(callLoc.getCallee(), scope, callerLoc);
302302

303303
} else if (auto fileLoc = dyn_cast<FileLineColLoc>(loc)) {
304-
llvm::DILocalScope *locationScope = scope;
305-
// Only construct a new DIFile when no local scope is present. This
306-
// prioritizes existing DI information when it's present.
307-
if (!locationScope) {
308-
auto *file = translateFile(fileLoc.getFilename());
309-
locationScope = llvm::DILexicalBlockFile::get(llvmCtx, scope, file,
310-
/*Discriminator=*/0);
311-
}
312-
llvmLoc = llvm::DILocation::get(llvmCtx, fileLoc.getLine(),
313-
fileLoc.getColumn(), locationScope,
314-
const_cast<llvm::DILocation *>(inlinedAt));
304+
// A scope of a DILocation cannot be null.
305+
if (!scope)
306+
return nullptr;
307+
llvmLoc =
308+
llvm::DILocation::get(llvmCtx, fileLoc.getLine(), fileLoc.getColumn(),
309+
scope, const_cast<llvm::DILocation *>(inlinedAt));
315310

316311
} else if (auto fusedLoc = dyn_cast<FusedLoc>(loc)) {
317312
ArrayRef<Location> locations = fusedLoc.getLocations();

mlir/test/Target/LLVMIR/llvmir-debug.mlir

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,30 @@ llvm.func @func_with_inlined_dbg_value(%arg0: i32) -> (i32) {
205205
// CHECK-DAG: ![[VAR_LOC0]] = !DILocalVariable(name: "a", scope: ![[OUTER_FUNC]], file: ![[FILE]]
206206
// CHECK-DAG: ![[VAR_LOC1]] = !DILocalVariable(name: "b", scope: ![[LEXICAL_BLOCK_FILE]], file: ![[FILE]]
207207
// CHECK-DAG ![[LABEL]] = !DILabel(scope: ![[LEXICAL_BLOCK_FILE]], name: "label", file: ![[FILE]], line: 42)
208+
209+
// -----
210+
211+
#di_basic_type = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int", sizeInBits = 32, encoding = DW_ATE_signed>
212+
#di_file = #llvm.di_file<"foo.mlir" in "/test/">
213+
#di_compile_unit = #llvm.di_compile_unit<
214+
sourceLanguage = DW_LANG_C, file = #di_file, producer = "MLIR",
215+
isOptimized = true, emissionKind = Full
216+
>
217+
#di_subprogram = #llvm.di_subprogram<
218+
compileUnit = #di_compile_unit, scope = #di_file, name = "func",
219+
file = #di_file, subprogramFlags = Definition>
220+
#di_local_variable = #llvm.di_local_variable<scope = #di_subprogram, name = "a", file = #di_file, type = #di_basic_type>
221+
222+
#loc = loc("foo.mlir":0:0)
223+
224+
// CHECK-LABEL: define void @func_without_subprogram(
225+
// CHECK-SAME: i32 %[[ARG:.*]])
226+
llvm.func @func_without_subprogram(%0 : i32) {
227+
// CHECK: call void @llvm.dbg.value(metadata i32 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG_LOC0:.*]]
228+
llvm.intr.dbg.value #di_local_variable = %0 : i32 loc(fused<#di_subprogram>[#loc])
229+
llvm.return
230+
}
231+
232+
// CHECK: ![[FILE:.*]] = !DIFile(filename: "foo.mlir", directory: "/test/")
233+
// CHECK-DAG: ![[FUNC:.*]] = distinct !DISubprogram(name: "func", scope: ![[FILE]]
234+
// CHECK-DAG: ![[VAR_LOC]] = !DILocalVariable(name: "a", scope: ![[FUNC]], file: ![[FILE]]

0 commit comments

Comments
 (0)