[Mlir-commits] [mlir] [MLIR][LLVM] Add DILocAttr for debug locations (PR #186146)
Alexander Yermolovich
llvmlistbot at llvm.org
Sun Mar 15 14:18:02 PDT 2026
https://github.com/ayermolo updated https://github.com/llvm/llvm-project/pull/186146
>From 8ad0cff8107c53c5bc9fd4aa80d7850aca75c491 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolovich at nvidia.com>
Date: Thu, 12 Mar 2026 15:19:59 +0000
Subject: [PATCH 1/4] [MLIR][LLVM] Add DILocAttr for debug locations
Introduces DILocAttr, a new MLIR location attribute that pairs a
FileLineColLoc with a DIScopeAttr to carry debug scope information
directly on locations instead of encoding it as FusedLoc metadata.
Replaces FusedLoc-with-metadata patterns across the LLVM dialect
transforms.
---
.../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 27 +++++++
.../Dialect/LLVMIR/LLVMDialectBytecode.td | 10 +++
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 2 +
.../Transforms/DIScopeForLLVMFuncOp.cpp | 73 ++++++++++---------
.../Transforms/InlinerInterfaceImpl.cpp | 13 ++--
mlir/lib/Target/LLVMIR/DebugImporter.cpp | 37 ++++++----
mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 27 +++++--
.../LLVMIR/LLVMToLLVMIRTranslation.cpp | 4 +
.../Target/LLVMIR/LoopAnnotationImporter.cpp | 20 ++++-
.../LLVMIR/add-debuginfo-func-scope.mlir | 6 +-
mlir/test/Dialect/LLVMIR/diloc-attr.mlir | 17 +++++
.../Dialect/LLVMIR/invalid-call-location.mlir | 33 +++++++++
mlir/test/Target/LLVMIR/Import/debug-info.ll | 28 +++----
13 files changed, 215 insertions(+), 82 deletions(-)
create mode 100644 mlir/test/Dialect/LLVMIR/diloc-attr.mlir
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 36acf244865eb..ccf7bef462786 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -642,6 +642,33 @@ def LLVM_DILexicalBlockFile : LLVM_Attr<"DILexicalBlockFile", "di_lexical_block_
let genMnemonicAlias = 1;
}
+//===----------------------------------------------------------------------===//
+// DILocAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_DILocAttr : LocationAttrDef<LLVM_Dialect, "DILoc"> {
+ let description = [{
+ Represents a debug location combining a source position and a debug info
+ scope. Replaces the convention-based FusedLoc encoding for instruction-level
+ and function-level debug locations.
+ }];
+ let mnemonic = "di_loc";
+
+ let parameters = (ins
+ "FileLineColLoc":$sourceLoc,
+ "DILocalScopeAttr":$scope
+ );
+ let assemblyFormat = "`<` $sourceLoc `in` $scope `>`";
+
+ let builders = [
+ AttrBuilderWithInferredContext<(ins
+ "FileLineColLoc":$sourceLoc, "DILocalScopeAttr":$scope
+ ), [{
+ return $_get(sourceLoc.getContext(), sourceLoc, scope);
+ }]>,
+ ];
+}
+
//===----------------------------------------------------------------------===//
// DILocalVariableAttr
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
index 659c535c1b671..3da283778d1ff 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
@@ -275,6 +275,15 @@ def DILexicalBlockFileAttr : DialectAttribute<(attr
VarInt:$discriminator
)>;
+//===----------------------------------------------------------------------===//
+// DILocAttr
+//===----------------------------------------------------------------------===//
+
+def DILocAttr : DialectAttribute<(attr
+ Attr<"FileLineColLoc">:$sourceLoc,
+ Attr<"DILocalScopeAttr">:$scope
+)>;
+
//===----------------------------------------------------------------------===//
// DINamespaceAttr
//===----------------------------------------------------------------------===//
@@ -338,6 +347,7 @@ def LLVMDialectAttributes : DialectAttributes<"LLVM"> {
DILabelAttr,
DILexicalBlockAttr,
DILexicalBlockFileAttr,
+ DILocAttr,
DILocalVariableAttr,
DINamespaceAttr,
DISubprogramAttr,
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index e5bafea345700..70709ea2f477c 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1142,6 +1142,8 @@ static LogicalResult verifyCallOpDebugInfo(CallOp callOp, LLVMFuncOp callee) {
return success();
auto hasSubprogram = [](Operation *op) {
+ if (auto diLoc = op->getLoc()->findInstanceOf<LLVM::DILocAttr>())
+ return isa<LLVM::DISubprogramAttr>(diLoc.getScope());
return op->getLoc()
->findInstanceOf<FusedLocWith<LLVM::DISubprogramAttr>>() !=
nullptr;
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
index 36b31ffc3970e..cb4cb7cab52a4 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
@@ -25,6 +25,8 @@ using namespace mlir;
static FileLineColLoc extractFileLoc(Location loc) {
if (auto fileLoc = dyn_cast<FileLineColLoc>(loc))
return fileLoc;
+ if (auto diLoc = dyn_cast<LLVM::DILocAttr>(loc))
+ return diLoc.getSourceLoc();
if (auto nameLoc = dyn_cast<NameLoc>(loc))
return extractFileLoc(nameLoc.getChildLoc());
if (auto opaqueLoc = dyn_cast<OpaqueLoc>(loc))
@@ -47,6 +49,9 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
LLVM::DICompileUnitAttr compileUnitAttr) {
Location loc = llvmFunc.getLoc();
+ if (auto diLoc = loc->findInstanceOf<LLVM::DILocAttr>())
+ if (isa<LLVM::DISubprogramAttr>(diLoc.getScope()))
+ return;
if (loc->findInstanceOf<FusedLocWith<LLVM::DISubprogramAttr>>())
return;
@@ -87,26 +92,30 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
fileAttr,
/*line=*/line, /*scopeLine=*/line, subprogramFlags, subroutineTypeAttr,
/*retainedNodes=*/{}, /*annotations=*/{});
- llvmFunc->setLoc(FusedLoc::get(context, {loc}, subprogramAttr));
+ FileLineColLoc fileLoc = extractFileLoc(loc);
+ if (!fileLoc)
+ fileLoc = FileLineColLoc::get(context, "<unknown>", line, /*column=*/0);
+ llvmFunc->setLoc(LLVM::DILocAttr::get(fileLoc, subprogramAttr));
}
-// Get a nested loc for inlined functions.
+// Build a DILocAttr for an inlined callee. Each recursion level creates a
+// DILexicalBlockFileAttr whose scope chains back through the caller scopes
+// to the enclosing subprogram. The scope nesting is carried by the
+// DILexicalBlockFileAttr hierarchy, not by nesting locations.
static Location getNestedLoc(Operation *op, LLVM::DIScopeAttr scopeAttr,
Location calleeLoc) {
- auto calleeFileName = extractFileLoc(calleeLoc).getFilename();
+ FileLineColLoc calleeFileLoc = extractFileLoc(calleeLoc);
auto *context = op->getContext();
+ StringAttr calleeFileName = calleeFileLoc.getFilename();
LLVM::DIFileAttr calleeFileAttr =
LLVM::DIFileAttr::get(context, llvm::sys::path::filename(calleeFileName),
llvm::sys::path::parent_path(calleeFileName));
auto lexicalBlockFileAttr = LLVM::DILexicalBlockFileAttr::get(
context, scopeAttr, calleeFileAttr, /*discriminator=*/0);
- Location loc = calleeLoc;
// Recurse if the callee location is again a call site.
- if (auto callSiteLoc = dyn_cast<CallSiteLoc>(calleeLoc)) {
- auto nestedLoc = callSiteLoc.getCallee();
- loc = getNestedLoc(op, lexicalBlockFileAttr, nestedLoc);
- }
- return FusedLoc::get(context, {loc}, lexicalBlockFileAttr);
+ if (auto callSiteLoc = dyn_cast<CallSiteLoc>(calleeLoc))
+ return getNestedLoc(op, lexicalBlockFileAttr, callSiteLoc.getCallee());
+ return LLVM::DILocAttr::get(calleeFileLoc, lexicalBlockFileAttr);
}
/// Adds DILexicalBlockFileAttr for operations with CallSiteLoc and operations
@@ -114,27 +123,27 @@ static Location getNestedLoc(Operation *op, LLVM::DIScopeAttr scopeAttr,
static void setLexicalBlockFileAttr(Operation *op) {
Location opLoc = op->getLoc();
- if (auto callSiteLoc = dyn_cast<CallSiteLoc>(opLoc)) {
- auto callerLoc = callSiteLoc.getCaller();
- auto calleeLoc = callSiteLoc.getCallee();
- LLVM::DIScopeAttr scopeAttr;
- // We assemble the full inline stack so the parent of this loc must be a
- // function
- if (auto funcOp = op->getParentOfType<LLVM::LLVMFuncOp>()) {
- if (auto funcOpLoc =
- llvm::dyn_cast_if_present<FusedLoc>(funcOp.getLoc())) {
- scopeAttr = cast<LLVM::DISubprogramAttr>(funcOpLoc.getMetadata());
- op->setLoc(CallSiteLoc::get(getNestedLoc(op, scopeAttr, calleeLoc),
- callerLoc));
- }
- }
-
+ auto funcOp = op->getParentOfType<LLVM::LLVMFuncOp>();
+ if (!funcOp)
return;
+
+ // Extract the subprogram scope from the function's location.
+ LLVM::DISubprogramAttr scopeAttr;
+ if (auto diLoc = funcOp.getLoc()->findInstanceOf<LLVM::DILocAttr>()) {
+ scopeAttr = dyn_cast<LLVM::DISubprogramAttr>(diLoc.getScope());
+ } else if (auto funcOpLoc =
+ llvm::dyn_cast_if_present<FusedLoc>(funcOp.getLoc())) {
+ scopeAttr = dyn_cast<LLVM::DISubprogramAttr>(funcOpLoc.getMetadata());
}
+ if (!scopeAttr)
+ return;
- auto funcOp = op->getParentOfType<LLVM::LLVMFuncOp>();
- if (!funcOp)
+ if (auto callSiteLoc = dyn_cast<CallSiteLoc>(opLoc)) {
+ op->setLoc(CallSiteLoc::get(
+ getNestedLoc(op, scopeAttr, callSiteLoc.getCallee()),
+ callSiteLoc.getCaller()));
return;
+ }
FileLineColLoc opFileLoc = extractFileLoc(opLoc);
if (!opFileLoc)
@@ -150,23 +159,15 @@ static void setLexicalBlockFileAttr(Operation *op) {
// Handle cross-file operations: add DILexicalBlockFileAttr when the
// operation's source file differs from its containing function.
if (opFile != funcFile) {
- auto funcOpLoc = llvm::dyn_cast_if_present<FusedLoc>(funcOp.getLoc());
- if (!funcOpLoc)
- return;
- auto scopeAttr = dyn_cast<LLVM::DISubprogramAttr>(funcOpLoc.getMetadata());
- if (!scopeAttr)
- return;
-
auto *context = op->getContext();
LLVM::DIFileAttr opFileAttr =
LLVM::DIFileAttr::get(context, llvm::sys::path::filename(opFile),
llvm::sys::path::parent_path(opFile));
- LLVM::DILexicalBlockFileAttr lexicalBlockFileAttr =
+ auto lexicalBlockFileAttr =
LLVM::DILexicalBlockFileAttr::get(context, scopeAttr, opFileAttr, 0);
- Location newLoc = FusedLoc::get(context, {opLoc}, lexicalBlockFileAttr);
- op->setLoc(newLoc);
+ op->setLoc(LLVM::DILocAttr::get(opFileLoc, lexicalBlockFileAttr));
}
}
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
index 680fafcc099f2..0b2dbc3a707f7 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
@@ -487,16 +487,15 @@ static void handleAccessGroups(Operation *call,
static void
handleLoopAnnotations(Operation *call,
iterator_range<Region::iterator> inlinedBlocks) {
- // Attempt to extract a DISubprogram from the callee.
+ // Attempt to extract a DISubprogram from the caller.
auto func = call->getParentOfType<FunctionOpInterface>();
if (!func)
return;
- LocationAttr funcLoc = func->getLoc();
- auto fusedLoc = dyn_cast_if_present<FusedLoc>(funcLoc);
- if (!fusedLoc)
- return;
- auto scope =
- dyn_cast_if_present<LLVM::DISubprogramAttr>(fusedLoc.getMetadata());
+ LLVM::DISubprogramAttr scope;
+ if (auto diLoc = func->getLoc()->findInstanceOf<LLVM::DILocAttr>())
+ scope = dyn_cast<LLVM::DISubprogramAttr>(diLoc.getScope());
+ else if (auto fusedLoc = dyn_cast_if_present<FusedLoc>(func->getLoc()))
+ scope = dyn_cast_if_present<LLVM::DISubprogramAttr>(fusedLoc.getMetadata());
if (!scope)
return;
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index 37140e3a949c7..2fe5f8a0a2b5b 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -33,11 +33,20 @@ Location DebugImporter::translateFuncLocation(llvm::Function *func) {
if (!subprogram)
return UnknownLoc::get(context);
- // Add a fused location to link the subprogram information.
StringAttr fileName = StringAttr::get(context, subprogram->getFilename());
- return FusedLocWith<DISubprogramAttr>::get(
- {FileLineColLoc::get(fileName, subprogram->getLine(), /*column=*/0)},
- translate(subprogram), context);
+ auto fileLoc =
+ FileLineColLoc::get(fileName, subprogram->getLine(), /*column=*/0);
+ auto scope =
+ dyn_cast_or_null<DILocalScopeAttr>(translate(subprogram));
+ // DILocAttr requires a non-null DILocalScopeAttr, but
+ // translateImpl(DISubprogram*) can return null when the subprogram's parent
+ // scope or subroutine type cannot be translated. Preserve the file location
+ // so diagnostics still have source info. This also matches the original
+ // FusedLocWith<DISubprogramAttr> behavior, where a null metadata caused the
+ // location to fail FusedLocWith<DISubprogramAttr> classof checks anyway.
+ if (!scope)
+ return fileLoc;
+ return DILocAttr::get(fileLoc, scope);
}
//===----------------------------------------------------------------------===//
@@ -465,19 +474,17 @@ Location DebugImporter::translateLoc(llvm::DILocation *loc) {
if (!loc)
return UnknownLoc::get(context);
- // Get the file location of the instruction.
- Location result = FileLineColLoc::get(context, loc->getFilename(),
- loc->getLine(), loc->getColumn());
-
- // Add scope information.
- assert(loc->getScope() && "expected non-null scope");
- result = FusedLocWith<DIScopeAttr>::get({result}, translate(loc->getScope()),
- context);
-
- // Add call site information, if available.
+ auto fileLoc = FileLineColLoc::get(context, loc->getFilename(),
+ loc->getLine(), loc->getColumn());
+ auto scope =
+ dyn_cast_or_null<DILocalScopeAttr>(translate(loc->getScope()));
+ // DILocAttr requires a non-null DILocalScopeAttr. When the scope cannot
+ // be translated, preserve the file location for diagnostics.
+ Location result = scope
+ ? Location(DILocAttr::get(fileLoc, scope))
+ : Location(fileLoc);
if (llvm::DILocation *inlinedAt = loc->getInlinedAt())
result = CallSiteLoc::get(result, translateLoc(inlinedAt));
-
return result;
}
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index 08eee68c195db..52e322f2bf9e6 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -61,12 +61,18 @@ void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
if (!debugEmissionIsEnabled)
return;
- // Look for a sub program attached to the function.
- auto spLoc =
- func.getLoc()->findInstanceOf<FusedLocWith<LLVM::DISubprogramAttr>>();
- if (!spLoc)
+ // Look for a subprogram: check DILocAttr first, fall back to FusedLoc.
+ LLVM::DISubprogramAttr sp;
+ if (auto diLoc = func.getLoc()->findInstanceOf<LLVM::DILocAttr>()) {
+ sp = dyn_cast<LLVM::DISubprogramAttr>(diLoc.getScope());
+ } else if (auto spLoc =
+ func.getLoc()
+ ->findInstanceOf<FusedLocWith<LLVM::DISubprogramAttr>>()) {
+ sp = spLoc.getMetadata();
+ }
+ if (!sp)
return;
- llvmFunc.setSubprogram(translate(spLoc.getMetadata()));
+ llvmFunc.setSubprogram(translate(sp));
}
//===----------------------------------------------------------------------===//
@@ -543,6 +549,17 @@ llvm::DILocation *DebugTranslation::translateLoc(Location loc,
if (!llvmLoc)
llvmLoc = callerLoc;
+ } else if (auto diLoc = dyn_cast<LLVM::DILocAttr>(loc)) {
+ // Translate the scope from the DILocAttr.
+ llvm::DILocalScope *diScope = translate(diLoc.getScope());
+ if (!diScope)
+ return nullptr;
+
+ auto sourceLoc = diLoc.getSourceLoc();
+ llvmLoc = llvm::DILocation::get(
+ llvmCtx, sourceLoc.getLine(), sourceLoc.getColumn(), diScope,
+ const_cast<llvm::DILocation *>(inlinedAt));
+
} else if (auto fileLoc = dyn_cast<FileLineColLoc>(loc)) {
// A scope of a DILocation cannot be null.
if (!scope)
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 21f7954fd338a..10d611dfee3a9 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -364,6 +364,10 @@ static void convertModuleFlagsOp(ArrayAttr flags, llvm::IRBuilderBase &builder,
static llvm::DILocalScope *
getLocalScopeFromLoc(llvm::IRBuilderBase &builder, Location loc,
LLVM::ModuleTranslation &moduleTranslation) {
+ if (auto diLoc = loc->findInstanceOf<LLVM::DILocAttr>())
+ if (auto *localScope = llvm::dyn_cast<llvm::DILocalScope>(
+ moduleTranslation.translateDebugInfo(diLoc.getScope())))
+ return localScope;
if (auto scopeLoc =
loc->findInstanceOf<FusedLocWith<LLVM::DILocalScopeAttr>>())
if (auto *localScope = llvm::dyn_cast<llvm::DILocalScope>(
diff --git a/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp b/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp
index e4905423347a2..7546bb09d1348 100644
--- a/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp
@@ -410,10 +410,26 @@ LoopMetadataConversion::convertParallelAccesses() {
return refs;
}
+/// Convert a translated location to a FusedLoc for loop annotation storage.
+/// translateLoc produces DILocAttr, but LoopAnnotationAttr stores locations as
+/// FusedLoc<scope>[raw_loc]. Extract the source location and scope from the
+/// DILocAttr to build the FusedLoc directly, matching the format expected by
+/// LoopAnnotationTranslation on the export side.
+static FusedLoc toFusedLoc(Location loc) {
+ if (auto fused = dyn_cast<FusedLoc>(loc))
+ return fused;
+ if (isa<UnknownLoc>(loc))
+ return {};
+ if (auto diLoc = dyn_cast<LLVM::DILocAttr>(loc))
+ return dyn_cast<FusedLoc>(FusedLoc::get(
+ {diLoc.getSourceLoc()}, diLoc.getScope(), loc.getContext()));
+ return {};
+}
+
FusedLoc LoopMetadataConversion::convertStartLoc() {
if (locations.empty())
return {};
- return dyn_cast<FusedLoc>(
+ return toFusedLoc(
loopAnnotationImporter.moduleImport.translateLoc(locations[0]));
}
@@ -423,7 +439,7 @@ FailureOr<FusedLoc> LoopMetadataConversion::convertEndLoc() {
if (locations.size() > 2)
return emitError(loc)
<< "expected loop metadata to have at most two DILocations";
- return dyn_cast<FusedLoc>(
+ return toFusedLoc(
loopAnnotationImporter.moduleImport.translateLoc(locations[1]));
}
diff --git a/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir b/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir
index 895c3fcb7fb23..30fc670846851 100644
--- a/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir
+++ b/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir
@@ -6,7 +6,7 @@
// CHECK: loc(#loc[[LOC:[0-9]+]])
// CHECK: #di_file = #llvm.di_file<"<unknown>" in "">
// CHECK: #di_subprogram = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #di_compile_unit, scope = #di_file, name = "func_no_debug", linkageName = "func_no_debug", file = #di_file, line = 1, scopeLine = 1, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type>
-// CHECK: #loc[[LOC]] = loc(fused<#di_subprogram>
+// CHECK: #loc[[LOC]] = #llvm.di_loc<{{.*}} in #di_subprogram>
module {
llvm.func @func_no_debug() {
llvm.return loc(unknown)
@@ -31,7 +31,7 @@ module {
// CHECK: loc(#loc[[LOC:[0-9]+]])
// CHECK: #di_file = #llvm.di_file<"<unknown>" in "">
// CHECK: #di_subprogram = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #di_compile_unit, scope = #di_file, name = "func_with_debug", linkageName = "func_with_debug", file = #di_file, line = 42, scopeLine = 42, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type>
-// CHECK: #loc[[LOC]] = loc(fused<#di_subprogram>
+// CHECK: #loc[[LOC]] = loc(fused<#di_subprogram>[
// CHECK_OTHER_KIND: emissionKind = DebugDirectivesOnly
module {
llvm.func @func_with_debug() {
@@ -59,7 +59,7 @@ module {
// CHECK-DAG: #di_compile_unit = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_C, file = #[[DI_FILE_MODULE]], producer = "MLIR", isOptimized = true, emissionKind = LineTablesOnly>
// CHECK-DAG: #di_subprogram = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #di_compile_unit, scope = #[[DI_FILE_FUNC]], name = "propagate_compile_unit", linkageName = "propagate_compile_unit", file = #[[DI_FILE_FUNC]], line = 9, scopeLine = 9, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type>
// CHECK-DAG: #loc[[MODULELOC]] = loc(fused<#di_compile_unit>[#loc])
-// CHECK-DAG: #loc[[FUNCLOC]] = loc(fused<#di_subprogram>[#loc[[FUNCFILELOC]]
+// CHECK-DAG: #loc[[FUNCLOC]] = #llvm.di_loc<#loc[[FUNCFILELOC]] in #di_subprogram>
module {
llvm.func @propagate_compile_unit() {
llvm.return loc(unknown)
diff --git a/mlir/test/Dialect/LLVMIR/diloc-attr.mlir b/mlir/test/Dialect/LLVMIR/diloc-attr.mlir
new file mode 100644
index 0000000000000..85abbb7783efb
--- /dev/null
+++ b/mlir/test/Dialect/LLVMIR/diloc-attr.mlir
@@ -0,0 +1,17 @@
+// RUN: mlir-opt %s --mlir-print-debuginfo | FileCheck %s
+//
+// Basic parse/print test for DILocAttr (no snapshots).
+// Uses a single source file and exercises two DILocAttr locations (module and function).
+
+#di_file = #llvm.di_file<"source.c" in "/">
+#di_compile_unit = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #di_file, isOptimized = false, emissionKind = None>
+#di_subprogram = #llvm.di_subprogram<compileUnit = #di_compile_unit, scope = #di_file, name = "test", file = #di_file, subprogramFlags = Definition>
+
+// CHECK-DAG: #llvm.di_loc<{{.*}} in #di_subprogram>
+// CHECK-DAG: #llvm.di_loc<{{.*}} in #di_subprogram>
+#loc_at_module = #llvm.di_loc<loc("source.c":1:1) in #di_subprogram>
+#loc_at_func = #llvm.di_loc<loc("source.c":10:2) in #di_subprogram>
+
+module {
+ llvm.func @f() {} loc(#loc_at_func)
+} loc(#loc_at_module)
diff --git a/mlir/test/Dialect/LLVMIR/invalid-call-location.mlir b/mlir/test/Dialect/LLVMIR/invalid-call-location.mlir
index 38b4ed9f6e83d..0272292874cdd 100644
--- a/mlir/test/Dialect/LLVMIR/invalid-call-location.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid-call-location.mlir
@@ -33,3 +33,36 @@ llvm.func @invalid_call_debug_locs() {
llvm.call @missing_debug_loc() : () -> () loc(#loc)
llvm.return
} loc(#loc4)
+
+// -----
+
+// Test the DILocAttr path of hasSubprogram.
+
+#di_file2 = #llvm.di_file<"file.cpp" in "/folder/">
+#di_compile_unit2 = #llvm.di_compile_unit<
+ id = distinct[0]<>, sourceLanguage = DW_LANG_C_plus_plus_14,
+ file = #di_file2, isOptimized = true, emissionKind = Full
+>
+#di_sp_callee = #llvm.di_subprogram<
+ compileUnit = #di_compile_unit2, scope = #di_file2,
+ name = "callee_diloc", file = #di_file2,
+ subprogramFlags = "Definition|Optimized"
+>
+#di_sp_caller = #llvm.di_subprogram<
+ compileUnit = #di_compile_unit2, scope = #di_file2,
+ name = "caller_diloc", file = #di_file2,
+ subprogramFlags = "Definition|Optimized"
+>
+#loc_unknown = loc(unknown)
+#loc_callee = #llvm.di_loc<loc("file.cpp":10:0) in #di_sp_callee>
+#loc_caller = #llvm.di_loc<loc("file.cpp":20:0) in #di_sp_caller>
+
+llvm.func @callee_diloc() {
+ llvm.return
+} loc(#loc_callee)
+
+llvm.func @caller_diloc() {
+// CHECK: <unknown>:0: error: inlinable function call in a function with a DISubprogram location must have a debug location
+ llvm.call @callee_diloc() : () -> () loc(#loc_unknown)
+ llvm.return
+} loc(#loc_caller)
diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll
index 3c2691217e0bf..f582d267cf8b8 100644
--- a/mlir/test/Target/LLVMIR/Import/debug-info.ll
+++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll
@@ -32,11 +32,11 @@ define i32 @instruction_loc(i32 %arg1) {
; CHECK-DAG: #[[RAW_FILE_LOC:.+]] = loc("debug-info.ll":1:2)
; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #{{.*}}, scope = #{{.*}}, name = "instruction_loc"
; CHECK-DAG: #[[CALLEE:.+]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #{{.*}}, scope = #{{.*}}, name = "callee"
-; CHECK-DAG: #[[FILE_LOC]] = loc(fused<#[[SP]]>[#[[RAW_FILE_LOC]]])
+; CHECK-DAG: #[[FILE_LOC]] = #llvm.di_loc<#[[RAW_FILE_LOC]] in #[[SP]]>
; CHECK-DAG: #[[RAW_CALLEE_LOC:.+]] = loc("debug-info.ll":7:4)
-; CHECK-DAG: #[[CALLEE_LOC:.+]] = loc(fused<#[[CALLEE]]>[#[[RAW_CALLEE_LOC]]])
+; CHECK-DAG: #[[CALLEE_LOC:.+]] = #llvm.di_loc<#[[RAW_CALLEE_LOC]] in #[[CALLEE]]>
; CHECK-DAG: #[[RAW_CALLER_LOC:.+]] = loc("debug-info.ll":2:2)
-; CHECK-DAG: #[[CALLER_LOC:.+]] = loc(fused<#[[SP]]>[#[[RAW_CALLER_LOC]]])
+; CHECK-DAG: #[[CALLER_LOC:.+]] = #llvm.di_loc<#[[RAW_CALLER_LOC]] in #[[SP]]>
; CHECK-DAG: #[[CALLSITE_LOC:.+]] = loc(callsite(#[[CALLEE_LOC]] at #[[CALLER_LOC]]))
!llvm.dbg.cu = !{!1}
@@ -66,8 +66,8 @@ define i32 @lexical_block(i32 %arg1) {
; CHECK: #[[SP:.+]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit =
; CHECK: #[[LB0:.+]] = #llvm.di_lexical_block<scope = #[[SP]]>
; CHECK: #[[LB1:.+]] = #llvm.di_lexical_block<scope = #[[SP]], file = #[[FILE]], line = 2, column = 2>
-; CHECK: #[[LOC0]] = loc(fused<#[[LB0]]>[{{.*}}])
-; CHECK: #[[LOC1]] = loc(fused<#[[LB1]]>[{{.*}}])
+; CHECK: #[[LOC0]] = #llvm.di_loc<{{.*}} in #[[LB0]]>
+; CHECK: #[[LOC1]] = #llvm.di_loc<{{.*}} in #[[LB1]]>
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -96,8 +96,8 @@ define i32 @lexical_block_file(i32 %arg1) {
; CHECK: #[[SP:.+]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit =
; CHECK: #[[LB0:.+]] = #llvm.di_lexical_block_file<scope = #[[SP]], discriminator = 0>
; CHECK: #[[LB1:.+]] = #llvm.di_lexical_block_file<scope = #[[SP]], file = #[[FILE]], discriminator = 0>
-; CHECK: #[[LOC0]] = loc(fused<#[[LB0]]>[
-; CHECK: #[[LOC1]] = loc(fused<#[[LB1]]>[
+; CHECK: #[[LOC0]] = #llvm.di_loc<{{.*}} in #[[LB0]]>
+; CHECK: #[[LOC1]] = #llvm.di_loc<{{.*}} in #[[LB1]]>
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -245,8 +245,7 @@ define void @func_loc() !dbg !3 {
}
; CHECK-DAG: #[[FILE_LOC:.+]] = loc("debug-info.ll":42:0)
; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #{{.*}}, scope = #{{.*}}, name = "func_loc", file = #{{.*}}, line = 42, subprogramFlags = Definition>
-
-; CHECK: loc(fused<#[[SP]]>[#[[FILE_LOC]]]
+; CHECK-DAG: #{{.+}} = #llvm.di_loc<#[[FILE_LOC]] in #[[SP]]>
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -287,8 +286,8 @@ define void @intrinsic(i64 %0, ptr %1) {
ret void
}
-; CHECK: #[[LOC1]] = loc(fused<#[[$SP]]>[{{.*}}])
-; CHECK: #[[LOC0]] = loc(fused<#[[$SP]]>[{{.*}}])
+; CHECK: #[[LOC1]] = #llvm.di_loc<{{.*}} in #[[$SP]]>
+; CHECK: #[[LOC0]] = #llvm.di_loc<{{.*}} in #[[$SP]]>
declare void @llvm.dbg.value(metadata, metadata, metadata)
declare void @llvm.dbg.declare(metadata, metadata, metadata)
@@ -322,7 +321,7 @@ define void @class_method() {
; CHECK-DAG: #[[COMP_PTR:.+]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, baseType = #[[COMP]], sizeInBits = 64, flags = "Artificial|ObjectPointer">
; CHECK-DAG: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type<types = #{{.*}}, #[[COMP_PTR]]>
; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram<recId = [[REC_ID]], id = [[SP_ID:.+]], compileUnit = #{{.*}}, scope = #[[COMP]], name = "class_method", file = #{{.*}}, subprogramFlags = Definition, type = #[[SP_TYPE]]>
-; CHECK-DAG: #[[LOC]] = loc(fused<#[[SP]]>
+; CHECK-DAG: #[[LOC]] = #llvm.di_loc<{{.*}} in #[[SP]]>
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -552,7 +551,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
; // -----
; CHECK: #[[SUBPROGRAM:.*]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #{{.*}}, scope = #{{.*}}, file = #{{.*}}, subprogramFlags = Definition>
-; CHECK: #[[FUNC_LOC:.*]] = loc(fused<#[[SUBPROGRAM]]>[{{.*}}])
+; CHECK: #[[FUNC_LOC:.*]] = #llvm.di_loc<{{.*}} in #[[SUBPROGRAM]]>
define void @noname_subprogram(ptr %arg) !dbg !8 {
ret void
}
@@ -618,7 +617,8 @@ declare !dbg !1 void @declaration()
; CHECK: #[[SP:.+]] = #llvm.di_subprogram<
; CHECK-NOT: id = distinct
; CHECK-NOT: subprogramFlags =
-; CHECK: loc(fused<#[[SP]]>
+; CHECK-SAME: >
+; CHECK: #{{.+}} = #llvm.di_loc<{{.*}} in #[[SP]]>
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"Debug Info Version", i32 3}
>From 4274bf0b7477362a696df09b070e7e15c1fea6fa Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolovich at nvidia.com>
Date: Thu, 12 Mar 2026 23:10:12 +0000
Subject: [PATCH 2/4] addressed comments
---
mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 6 ++++--
.../LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp | 16 +++++++++-------
.../LLVMIR/Transforms/InlinerInterfaceImpl.cpp | 4 ++--
mlir/lib/Target/LLVMIR/DebugImporter.cpp | 13 ++++++-------
mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 10 +++++-----
5 files changed, 26 insertions(+), 23 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index ccf7bef462786..a7d3a404d383c 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -649,8 +649,10 @@ def LLVM_DILexicalBlockFile : LLVM_Attr<"DILexicalBlockFile", "di_lexical_block_
def LLVM_DILocAttr : LocationAttrDef<LLVM_Dialect, "DILoc"> {
let description = [{
Represents a debug location combining a source position and a debug info
- scope. Replaces the convention-based FusedLoc encoding for instruction-level
- and function-level debug locations.
+ scope for instruction-level and function-level debug locations.
+
+ Note: Older code represented this with a FusedLoc carrying the debug
+ scope as its metadata and a convention on how to interpret it.
}];
let mnemonic = "di_loc";
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
index cb4cb7cab52a4..bd092b0a6650b 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
@@ -49,7 +49,7 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
LLVM::DICompileUnitAttr compileUnitAttr) {
Location loc = llvmFunc.getLoc();
- if (auto diLoc = loc->findInstanceOf<LLVM::DILocAttr>())
+ if (auto diLoc = dyn_cast_if_present<LLVM::DILocAttr>(loc))
if (isa<LLVM::DISubprogramAttr>(diLoc.getScope()))
return;
if (loc->findInstanceOf<FusedLocWith<LLVM::DISubprogramAttr>>())
@@ -94,7 +94,7 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
/*retainedNodes=*/{}, /*annotations=*/{});
FileLineColLoc fileLoc = extractFileLoc(loc);
if (!fileLoc)
- fileLoc = FileLineColLoc::get(context, "<unknown>", line, /*column=*/0);
+ fileLoc = FileLineColLoc::get(context, "", line, /*column=*/0);
llvmFunc->setLoc(LLVM::DILocAttr::get(fileLoc, subprogramAttr));
}
@@ -106,6 +106,8 @@ static Location getNestedLoc(Operation *op, LLVM::DIScopeAttr scopeAttr,
Location calleeLoc) {
FileLineColLoc calleeFileLoc = extractFileLoc(calleeLoc);
auto *context = op->getContext();
+ if (!calleeFileLoc)
+ calleeFileLoc = FileLineColLoc::get(context, "", 0, 0);
StringAttr calleeFileName = calleeFileLoc.getFilename();
LLVM::DIFileAttr calleeFileAttr =
LLVM::DIFileAttr::get(context, llvm::sys::path::filename(calleeFileName),
@@ -129,8 +131,8 @@ static void setLexicalBlockFileAttr(Operation *op) {
// Extract the subprogram scope from the function's location.
LLVM::DISubprogramAttr scopeAttr;
- if (auto diLoc = funcOp.getLoc()->findInstanceOf<LLVM::DILocAttr>()) {
- scopeAttr = dyn_cast<LLVM::DISubprogramAttr>(diLoc.getScope());
+ if (auto diLoc = dyn_cast_if_present<LLVM::DILocAttr>(funcOp.getLoc())) {
+ scopeAttr = dyn_cast_if_present<LLVM::DISubprogramAttr>(diLoc.getScope());
} else if (auto funcOpLoc =
llvm::dyn_cast_if_present<FusedLoc>(funcOp.getLoc())) {
scopeAttr = dyn_cast<LLVM::DISubprogramAttr>(funcOpLoc.getMetadata());
@@ -139,9 +141,9 @@ static void setLexicalBlockFileAttr(Operation *op) {
return;
if (auto callSiteLoc = dyn_cast<CallSiteLoc>(opLoc)) {
- op->setLoc(CallSiteLoc::get(
- getNestedLoc(op, scopeAttr, callSiteLoc.getCallee()),
- callSiteLoc.getCaller()));
+ op->setLoc(
+ CallSiteLoc::get(getNestedLoc(op, scopeAttr, callSiteLoc.getCallee()),
+ callSiteLoc.getCaller()));
return;
}
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
index 0b2dbc3a707f7..edebd536638c7 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
@@ -492,8 +492,8 @@ handleLoopAnnotations(Operation *call,
if (!func)
return;
LLVM::DISubprogramAttr scope;
- if (auto diLoc = func->getLoc()->findInstanceOf<LLVM::DILocAttr>())
- scope = dyn_cast<LLVM::DISubprogramAttr>(diLoc.getScope());
+ if (auto diLoc = dyn_cast_if_present<LLVM::DILocAttr>(func->getLoc()))
+ scope = dyn_cast_if_present<LLVM::DISubprogramAttr>(diLoc.getScope());
else if (auto fusedLoc = dyn_cast_if_present<FusedLoc>(func->getLoc()))
scope = dyn_cast_if_present<LLVM::DISubprogramAttr>(fusedLoc.getMetadata());
if (!scope)
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index 2fe5f8a0a2b5b..b97ef9f19659f 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -36,8 +36,7 @@ Location DebugImporter::translateFuncLocation(llvm::Function *func) {
StringAttr fileName = StringAttr::get(context, subprogram->getFilename());
auto fileLoc =
FileLineColLoc::get(fileName, subprogram->getLine(), /*column=*/0);
- auto scope =
- dyn_cast_or_null<DILocalScopeAttr>(translate(subprogram));
+ auto scope = dyn_cast_if_present<DILocalScopeAttr>(translate(subprogram));
// DILocAttr requires a non-null DILocalScopeAttr, but
// translateImpl(DISubprogram*) can return null when the subprogram's parent
// scope or subroutine type cannot be translated. Preserve the file location
@@ -475,16 +474,16 @@ Location DebugImporter::translateLoc(llvm::DILocation *loc) {
return UnknownLoc::get(context);
auto fileLoc = FileLineColLoc::get(context, loc->getFilename(),
- loc->getLine(), loc->getColumn());
+ loc->getLine(), loc->getColumn());
auto scope =
- dyn_cast_or_null<DILocalScopeAttr>(translate(loc->getScope()));
+ dyn_cast_if_present<DILocalScopeAttr>(translate(loc->getScope()));
// DILocAttr requires a non-null DILocalScopeAttr. When the scope cannot
// be translated, preserve the file location for diagnostics.
- Location result = scope
- ? Location(DILocAttr::get(fileLoc, scope))
- : Location(fileLoc);
+ Location result =
+ scope ? Location(DILocAttr::get(fileLoc, scope)) : Location(fileLoc);
if (llvm::DILocation *inlinedAt = loc->getInlinedAt())
result = CallSiteLoc::get(result, translateLoc(inlinedAt));
+
return result;
}
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index 52e322f2bf9e6..ef16e2602da2e 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -63,8 +63,8 @@ void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
// Look for a subprogram: check DILocAttr first, fall back to FusedLoc.
LLVM::DISubprogramAttr sp;
- if (auto diLoc = func.getLoc()->findInstanceOf<LLVM::DILocAttr>()) {
- sp = dyn_cast<LLVM::DISubprogramAttr>(diLoc.getScope());
+ if (auto diLoc = dyn_cast_if_present<LLVM::DILocAttr>(func.getLoc())) {
+ sp = dyn_cast_if_present<LLVM::DISubprogramAttr>(diLoc.getScope());
} else if (auto spLoc =
func.getLoc()
->findInstanceOf<FusedLocWith<LLVM::DISubprogramAttr>>()) {
@@ -556,9 +556,9 @@ llvm::DILocation *DebugTranslation::translateLoc(Location loc,
return nullptr;
auto sourceLoc = diLoc.getSourceLoc();
- llvmLoc = llvm::DILocation::get(
- llvmCtx, sourceLoc.getLine(), sourceLoc.getColumn(), diScope,
- const_cast<llvm::DILocation *>(inlinedAt));
+ llvmLoc = llvm::DILocation::get(llvmCtx, sourceLoc.getLine(),
+ sourceLoc.getColumn(), diScope,
+ const_cast<llvm::DILocation *>(inlinedAt));
} else if (auto fileLoc = dyn_cast<FileLineColLoc>(loc)) {
// A scope of a DILocation cannot be null.
>From 25787dc78d5494cd13e57824fb79675c311008ca Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolovich at nvidia.com>
Date: Thu, 12 Mar 2026 23:51:57 +0000
Subject: [PATCH 3/4] fix build issue
---
.../lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
index bd092b0a6650b..ef2337eee36a2 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
@@ -47,11 +47,12 @@ static FileLineColLoc extractFileLoc(Location loc) {
/// subprogram.
static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
LLVM::DICompileUnitAttr compileUnitAttr) {
-
- Location loc = llvmFunc.getLoc();
- if (auto diLoc = dyn_cast_if_present<LLVM::DILocAttr>(loc))
+ // Use getLoc() directly so the result is an rvalue; ValueIsPresent<Location>
+ // lacks unwrapValue, so dyn_cast_if_present fails on lvalue Locations.
+ if (auto diLoc = dyn_cast_if_present<LLVM::DILocAttr>(llvmFunc.getLoc()))
if (isa<LLVM::DISubprogramAttr>(diLoc.getScope()))
return;
+ Location loc = llvmFunc.getLoc();
if (loc->findInstanceOf<FusedLocWith<LLVM::DISubprogramAttr>>())
return;
>From e665b23be3a5fa5c0210dc13670652a2c3fcdebb Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolovich at nvidia.com>
Date: Sun, 15 Mar 2026 21:17:43 +0000
Subject: [PATCH 4/4] Changed to DILocationAttr
---
.../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 8 +++---
.../Dialect/LLVMIR/LLVMDialectBytecode.td | 6 ++---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 2 +-
.../Transforms/DIScopeForLLVMFuncOp.cpp | 14 +++++-----
.../Transforms/InlinerInterfaceImpl.cpp | 2 +-
mlir/lib/Target/LLVMIR/DebugImporter.cpp | 8 +++---
mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 8 +++---
.../LLVMIR/LLVMToLLVMIRTranslation.cpp | 2 +-
.../Target/LLVMIR/LoopAnnotationImporter.cpp | 10 +++----
.../LLVMIR/add-debuginfo-func-scope.mlir | 4 +--
mlir/test/Dialect/LLVMIR/diloc-attr.mlir | 12 ++++-----
.../Dialect/LLVMIR/invalid-call-location.mlir | 6 ++---
mlir/test/Target/LLVMIR/Import/debug-info.ll | 26 +++++++++----------
13 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index a7d3a404d383c..6a8188f731436 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -643,18 +643,18 @@ def LLVM_DILexicalBlockFile : LLVM_Attr<"DILexicalBlockFile", "di_lexical_block_
}
//===----------------------------------------------------------------------===//
-// DILocAttr
+// DILocationAttr
//===----------------------------------------------------------------------===//
-def LLVM_DILocAttr : LocationAttrDef<LLVM_Dialect, "DILoc"> {
+def LLVM_DILocationAttr : LocationAttrDef<LLVM_Dialect, "DILocation"> {
let description = [{
Represents a debug location combining a source position and a debug info
scope for instruction-level and function-level debug locations.
- Note: Older code represented this with a FusedLoc carrying the debug
+ Note: Older code represents this with a FusedLoc carrying the debug
scope as its metadata and a convention on how to interpret it.
}];
- let mnemonic = "di_loc";
+ let mnemonic = "di_location";
let parameters = (ins
"FileLineColLoc":$sourceLoc,
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
index 3da283778d1ff..051f1eebda418 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
@@ -276,10 +276,10 @@ def DILexicalBlockFileAttr : DialectAttribute<(attr
)>;
//===----------------------------------------------------------------------===//
-// DILocAttr
+// DILocationAttr
//===----------------------------------------------------------------------===//
-def DILocAttr : DialectAttribute<(attr
+def DILocationAttr : DialectAttribute<(attr
Attr<"FileLineColLoc">:$sourceLoc,
Attr<"DILocalScopeAttr">:$scope
)>;
@@ -347,7 +347,7 @@ def LLVMDialectAttributes : DialectAttributes<"LLVM"> {
DILabelAttr,
DILexicalBlockAttr,
DILexicalBlockFileAttr,
- DILocAttr,
+ DILocationAttr,
DILocalVariableAttr,
DINamespaceAttr,
DISubprogramAttr,
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 70709ea2f477c..ec03940626abe 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1142,7 +1142,7 @@ static LogicalResult verifyCallOpDebugInfo(CallOp callOp, LLVMFuncOp callee) {
return success();
auto hasSubprogram = [](Operation *op) {
- if (auto diLoc = op->getLoc()->findInstanceOf<LLVM::DILocAttr>())
+ if (auto diLoc = op->getLoc()->findInstanceOf<LLVM::DILocationAttr>())
return isa<LLVM::DISubprogramAttr>(diLoc.getScope());
return op->getLoc()
->findInstanceOf<FusedLocWith<LLVM::DISubprogramAttr>>() !=
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
index ef2337eee36a2..261b5eb23e241 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
@@ -25,7 +25,7 @@ using namespace mlir;
static FileLineColLoc extractFileLoc(Location loc) {
if (auto fileLoc = dyn_cast<FileLineColLoc>(loc))
return fileLoc;
- if (auto diLoc = dyn_cast<LLVM::DILocAttr>(loc))
+ if (auto diLoc = dyn_cast<LLVM::DILocationAttr>(loc))
return diLoc.getSourceLoc();
if (auto nameLoc = dyn_cast<NameLoc>(loc))
return extractFileLoc(nameLoc.getChildLoc());
@@ -49,7 +49,7 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
LLVM::DICompileUnitAttr compileUnitAttr) {
// Use getLoc() directly so the result is an rvalue; ValueIsPresent<Location>
// lacks unwrapValue, so dyn_cast_if_present fails on lvalue Locations.
- if (auto diLoc = dyn_cast_if_present<LLVM::DILocAttr>(llvmFunc.getLoc()))
+ if (auto diLoc = dyn_cast_if_present<LLVM::DILocationAttr>(llvmFunc.getLoc()))
if (isa<LLVM::DISubprogramAttr>(diLoc.getScope()))
return;
Location loc = llvmFunc.getLoc();
@@ -96,10 +96,10 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
FileLineColLoc fileLoc = extractFileLoc(loc);
if (!fileLoc)
fileLoc = FileLineColLoc::get(context, "", line, /*column=*/0);
- llvmFunc->setLoc(LLVM::DILocAttr::get(fileLoc, subprogramAttr));
+ llvmFunc->setLoc(LLVM::DILocationAttr::get(fileLoc, subprogramAttr));
}
-// Build a DILocAttr for an inlined callee. Each recursion level creates a
+// Build a DILocationAttr for an inlined callee. Each recursion level creates a
// DILexicalBlockFileAttr whose scope chains back through the caller scopes
// to the enclosing subprogram. The scope nesting is carried by the
// DILexicalBlockFileAttr hierarchy, not by nesting locations.
@@ -118,7 +118,7 @@ static Location getNestedLoc(Operation *op, LLVM::DIScopeAttr scopeAttr,
// Recurse if the callee location is again a call site.
if (auto callSiteLoc = dyn_cast<CallSiteLoc>(calleeLoc))
return getNestedLoc(op, lexicalBlockFileAttr, callSiteLoc.getCallee());
- return LLVM::DILocAttr::get(calleeFileLoc, lexicalBlockFileAttr);
+ return LLVM::DILocationAttr::get(calleeFileLoc, lexicalBlockFileAttr);
}
/// Adds DILexicalBlockFileAttr for operations with CallSiteLoc and operations
@@ -132,7 +132,7 @@ static void setLexicalBlockFileAttr(Operation *op) {
// Extract the subprogram scope from the function's location.
LLVM::DISubprogramAttr scopeAttr;
- if (auto diLoc = dyn_cast_if_present<LLVM::DILocAttr>(funcOp.getLoc())) {
+ if (auto diLoc = dyn_cast_if_present<LLVM::DILocationAttr>(funcOp.getLoc())) {
scopeAttr = dyn_cast_if_present<LLVM::DISubprogramAttr>(diLoc.getScope());
} else if (auto funcOpLoc =
llvm::dyn_cast_if_present<FusedLoc>(funcOp.getLoc())) {
@@ -170,7 +170,7 @@ static void setLexicalBlockFileAttr(Operation *op) {
auto lexicalBlockFileAttr =
LLVM::DILexicalBlockFileAttr::get(context, scopeAttr, opFileAttr, 0);
- op->setLoc(LLVM::DILocAttr::get(opFileLoc, lexicalBlockFileAttr));
+ op->setLoc(LLVM::DILocationAttr::get(opFileLoc, lexicalBlockFileAttr));
}
}
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
index edebd536638c7..47a15ec968c96 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp
@@ -492,7 +492,7 @@ handleLoopAnnotations(Operation *call,
if (!func)
return;
LLVM::DISubprogramAttr scope;
- if (auto diLoc = dyn_cast_if_present<LLVM::DILocAttr>(func->getLoc()))
+ if (auto diLoc = dyn_cast_if_present<LLVM::DILocationAttr>(func->getLoc()))
scope = dyn_cast_if_present<LLVM::DISubprogramAttr>(diLoc.getScope());
else if (auto fusedLoc = dyn_cast_if_present<FusedLoc>(func->getLoc()))
scope = dyn_cast_if_present<LLVM::DISubprogramAttr>(fusedLoc.getMetadata());
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index b97ef9f19659f..b059453737dc4 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -37,7 +37,7 @@ Location DebugImporter::translateFuncLocation(llvm::Function *func) {
auto fileLoc =
FileLineColLoc::get(fileName, subprogram->getLine(), /*column=*/0);
auto scope = dyn_cast_if_present<DILocalScopeAttr>(translate(subprogram));
- // DILocAttr requires a non-null DILocalScopeAttr, but
+ // DILocationAttr requires a non-null DILocalScopeAttr, but
// translateImpl(DISubprogram*) can return null when the subprogram's parent
// scope or subroutine type cannot be translated. Preserve the file location
// so diagnostics still have source info. This also matches the original
@@ -45,7 +45,7 @@ Location DebugImporter::translateFuncLocation(llvm::Function *func) {
// location to fail FusedLocWith<DISubprogramAttr> classof checks anyway.
if (!scope)
return fileLoc;
- return DILocAttr::get(fileLoc, scope);
+ return DILocationAttr::get(fileLoc, scope);
}
//===----------------------------------------------------------------------===//
@@ -477,10 +477,10 @@ Location DebugImporter::translateLoc(llvm::DILocation *loc) {
loc->getLine(), loc->getColumn());
auto scope =
dyn_cast_if_present<DILocalScopeAttr>(translate(loc->getScope()));
- // DILocAttr requires a non-null DILocalScopeAttr. When the scope cannot
+ // DILocationAttr requires a non-null DILocalScopeAttr. When the scope cannot
// be translated, preserve the file location for diagnostics.
Location result =
- scope ? Location(DILocAttr::get(fileLoc, scope)) : Location(fileLoc);
+ scope ? Location(DILocationAttr::get(fileLoc, scope)) : Location(fileLoc);
if (llvm::DILocation *inlinedAt = loc->getInlinedAt())
result = CallSiteLoc::get(result, translateLoc(inlinedAt));
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index ef16e2602da2e..4068e025903ed 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -61,9 +61,9 @@ void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
if (!debugEmissionIsEnabled)
return;
- // Look for a subprogram: check DILocAttr first, fall back to FusedLoc.
+ // Look for a subprogram: check DILocationAttr first, fall back to FusedLoc.
LLVM::DISubprogramAttr sp;
- if (auto diLoc = dyn_cast_if_present<LLVM::DILocAttr>(func.getLoc())) {
+ if (auto diLoc = dyn_cast_if_present<LLVM::DILocationAttr>(func.getLoc())) {
sp = dyn_cast_if_present<LLVM::DISubprogramAttr>(diLoc.getScope());
} else if (auto spLoc =
func.getLoc()
@@ -549,8 +549,8 @@ llvm::DILocation *DebugTranslation::translateLoc(Location loc,
if (!llvmLoc)
llvmLoc = callerLoc;
- } else if (auto diLoc = dyn_cast<LLVM::DILocAttr>(loc)) {
- // Translate the scope from the DILocAttr.
+ } else if (auto diLoc = dyn_cast<LLVM::DILocationAttr>(loc)) {
+ // Translate the scope from the DILocationAttr.
llvm::DILocalScope *diScope = translate(diLoc.getScope());
if (!diScope)
return nullptr;
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 10d611dfee3a9..cc2b9676512c1 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -364,7 +364,7 @@ static void convertModuleFlagsOp(ArrayAttr flags, llvm::IRBuilderBase &builder,
static llvm::DILocalScope *
getLocalScopeFromLoc(llvm::IRBuilderBase &builder, Location loc,
LLVM::ModuleTranslation &moduleTranslation) {
- if (auto diLoc = loc->findInstanceOf<LLVM::DILocAttr>())
+ if (auto diLoc = loc->findInstanceOf<LLVM::DILocationAttr>())
if (auto *localScope = llvm::dyn_cast<llvm::DILocalScope>(
moduleTranslation.translateDebugInfo(diLoc.getScope())))
return localScope;
diff --git a/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp b/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp
index 7546bb09d1348..1c966c7600bb5 100644
--- a/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp
@@ -411,16 +411,16 @@ LoopMetadataConversion::convertParallelAccesses() {
}
/// Convert a translated location to a FusedLoc for loop annotation storage.
-/// translateLoc produces DILocAttr, but LoopAnnotationAttr stores locations as
-/// FusedLoc<scope>[raw_loc]. Extract the source location and scope from the
-/// DILocAttr to build the FusedLoc directly, matching the format expected by
-/// LoopAnnotationTranslation on the export side.
+/// translateLoc produces DILocationAttr, but LoopAnnotationAttr stores
+/// locations as FusedLoc<scope>[raw_loc]. Extract the source location and scope
+/// from the DILocationAttr to build the FusedLoc directly, matching the format
+/// expected by LoopAnnotationTranslation on the export side.
static FusedLoc toFusedLoc(Location loc) {
if (auto fused = dyn_cast<FusedLoc>(loc))
return fused;
if (isa<UnknownLoc>(loc))
return {};
- if (auto diLoc = dyn_cast<LLVM::DILocAttr>(loc))
+ if (auto diLoc = dyn_cast<LLVM::DILocationAttr>(loc))
return dyn_cast<FusedLoc>(FusedLoc::get(
{diLoc.getSourceLoc()}, diLoc.getScope(), loc.getContext()));
return {};
diff --git a/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir b/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir
index 30fc670846851..517aa6da169ee 100644
--- a/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir
+++ b/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir
@@ -6,7 +6,7 @@
// CHECK: loc(#loc[[LOC:[0-9]+]])
// CHECK: #di_file = #llvm.di_file<"<unknown>" in "">
// CHECK: #di_subprogram = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #di_compile_unit, scope = #di_file, name = "func_no_debug", linkageName = "func_no_debug", file = #di_file, line = 1, scopeLine = 1, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type>
-// CHECK: #loc[[LOC]] = #llvm.di_loc<{{.*}} in #di_subprogram>
+// CHECK: #loc[[LOC]] = #llvm.di_location<{{.*}} in #di_subprogram>
module {
llvm.func @func_no_debug() {
llvm.return loc(unknown)
@@ -59,7 +59,7 @@ module {
// CHECK-DAG: #di_compile_unit = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_C, file = #[[DI_FILE_MODULE]], producer = "MLIR", isOptimized = true, emissionKind = LineTablesOnly>
// CHECK-DAG: #di_subprogram = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #di_compile_unit, scope = #[[DI_FILE_FUNC]], name = "propagate_compile_unit", linkageName = "propagate_compile_unit", file = #[[DI_FILE_FUNC]], line = 9, scopeLine = 9, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type>
// CHECK-DAG: #loc[[MODULELOC]] = loc(fused<#di_compile_unit>[#loc])
-// CHECK-DAG: #loc[[FUNCLOC]] = #llvm.di_loc<#loc[[FUNCFILELOC]] in #di_subprogram>
+// CHECK-DAG: #loc[[FUNCLOC]] = #llvm.di_location<#loc[[FUNCFILELOC]] in #di_subprogram>
module {
llvm.func @propagate_compile_unit() {
llvm.return loc(unknown)
diff --git a/mlir/test/Dialect/LLVMIR/diloc-attr.mlir b/mlir/test/Dialect/LLVMIR/diloc-attr.mlir
index 85abbb7783efb..e0d04eff29154 100644
--- a/mlir/test/Dialect/LLVMIR/diloc-attr.mlir
+++ b/mlir/test/Dialect/LLVMIR/diloc-attr.mlir
@@ -1,16 +1,16 @@
// RUN: mlir-opt %s --mlir-print-debuginfo | FileCheck %s
//
-// Basic parse/print test for DILocAttr (no snapshots).
-// Uses a single source file and exercises two DILocAttr locations (module and function).
+// Basic parse/print test for DILocationAttr (no snapshots).
+// Uses a single source file and exercises two DILocationAttr locations (module and function).
#di_file = #llvm.di_file<"source.c" in "/">
#di_compile_unit = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #di_file, isOptimized = false, emissionKind = None>
#di_subprogram = #llvm.di_subprogram<compileUnit = #di_compile_unit, scope = #di_file, name = "test", file = #di_file, subprogramFlags = Definition>
-// CHECK-DAG: #llvm.di_loc<{{.*}} in #di_subprogram>
-// CHECK-DAG: #llvm.di_loc<{{.*}} in #di_subprogram>
-#loc_at_module = #llvm.di_loc<loc("source.c":1:1) in #di_subprogram>
-#loc_at_func = #llvm.di_loc<loc("source.c":10:2) in #di_subprogram>
+// CHECK-DAG: #llvm.di_location<{{.*}} in #di_subprogram>
+// CHECK-DAG: #llvm.di_location<{{.*}} in #di_subprogram>
+#loc_at_module = #llvm.di_location<loc("source.c":1:1) in #di_subprogram>
+#loc_at_func = #llvm.di_location<loc("source.c":10:2) in #di_subprogram>
module {
llvm.func @f() {} loc(#loc_at_func)
diff --git a/mlir/test/Dialect/LLVMIR/invalid-call-location.mlir b/mlir/test/Dialect/LLVMIR/invalid-call-location.mlir
index 0272292874cdd..9cd12242afbd1 100644
--- a/mlir/test/Dialect/LLVMIR/invalid-call-location.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid-call-location.mlir
@@ -36,7 +36,7 @@ llvm.func @invalid_call_debug_locs() {
// -----
-// Test the DILocAttr path of hasSubprogram.
+// Test the DILocationAttr path of hasSubprogram.
#di_file2 = #llvm.di_file<"file.cpp" in "/folder/">
#di_compile_unit2 = #llvm.di_compile_unit<
@@ -54,8 +54,8 @@ llvm.func @invalid_call_debug_locs() {
subprogramFlags = "Definition|Optimized"
>
#loc_unknown = loc(unknown)
-#loc_callee = #llvm.di_loc<loc("file.cpp":10:0) in #di_sp_callee>
-#loc_caller = #llvm.di_loc<loc("file.cpp":20:0) in #di_sp_caller>
+#loc_callee = #llvm.di_location<loc("file.cpp":10:0) in #di_sp_callee>
+#loc_caller = #llvm.di_location<loc("file.cpp":20:0) in #di_sp_caller>
llvm.func @callee_diloc() {
llvm.return
diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll
index f582d267cf8b8..88faf5aa9c08f 100644
--- a/mlir/test/Target/LLVMIR/Import/debug-info.ll
+++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll
@@ -32,11 +32,11 @@ define i32 @instruction_loc(i32 %arg1) {
; CHECK-DAG: #[[RAW_FILE_LOC:.+]] = loc("debug-info.ll":1:2)
; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #{{.*}}, scope = #{{.*}}, name = "instruction_loc"
; CHECK-DAG: #[[CALLEE:.+]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #{{.*}}, scope = #{{.*}}, name = "callee"
-; CHECK-DAG: #[[FILE_LOC]] = #llvm.di_loc<#[[RAW_FILE_LOC]] in #[[SP]]>
+; CHECK-DAG: #[[FILE_LOC]] = #llvm.di_location<#[[RAW_FILE_LOC]] in #[[SP]]>
; CHECK-DAG: #[[RAW_CALLEE_LOC:.+]] = loc("debug-info.ll":7:4)
-; CHECK-DAG: #[[CALLEE_LOC:.+]] = #llvm.di_loc<#[[RAW_CALLEE_LOC]] in #[[CALLEE]]>
+; CHECK-DAG: #[[CALLEE_LOC:.+]] = #llvm.di_location<#[[RAW_CALLEE_LOC]] in #[[CALLEE]]>
; CHECK-DAG: #[[RAW_CALLER_LOC:.+]] = loc("debug-info.ll":2:2)
-; CHECK-DAG: #[[CALLER_LOC:.+]] = #llvm.di_loc<#[[RAW_CALLER_LOC]] in #[[SP]]>
+; CHECK-DAG: #[[CALLER_LOC:.+]] = #llvm.di_location<#[[RAW_CALLER_LOC]] in #[[SP]]>
; CHECK-DAG: #[[CALLSITE_LOC:.+]] = loc(callsite(#[[CALLEE_LOC]] at #[[CALLER_LOC]]))
!llvm.dbg.cu = !{!1}
@@ -66,8 +66,8 @@ define i32 @lexical_block(i32 %arg1) {
; CHECK: #[[SP:.+]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit =
; CHECK: #[[LB0:.+]] = #llvm.di_lexical_block<scope = #[[SP]]>
; CHECK: #[[LB1:.+]] = #llvm.di_lexical_block<scope = #[[SP]], file = #[[FILE]], line = 2, column = 2>
-; CHECK: #[[LOC0]] = #llvm.di_loc<{{.*}} in #[[LB0]]>
-; CHECK: #[[LOC1]] = #llvm.di_loc<{{.*}} in #[[LB1]]>
+; CHECK: #[[LOC0]] = #llvm.di_location<{{.*}} in #[[LB0]]>
+; CHECK: #[[LOC1]] = #llvm.di_location<{{.*}} in #[[LB1]]>
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -96,8 +96,8 @@ define i32 @lexical_block_file(i32 %arg1) {
; CHECK: #[[SP:.+]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit =
; CHECK: #[[LB0:.+]] = #llvm.di_lexical_block_file<scope = #[[SP]], discriminator = 0>
; CHECK: #[[LB1:.+]] = #llvm.di_lexical_block_file<scope = #[[SP]], file = #[[FILE]], discriminator = 0>
-; CHECK: #[[LOC0]] = #llvm.di_loc<{{.*}} in #[[LB0]]>
-; CHECK: #[[LOC1]] = #llvm.di_loc<{{.*}} in #[[LB1]]>
+; CHECK: #[[LOC0]] = #llvm.di_location<{{.*}} in #[[LB0]]>
+; CHECK: #[[LOC1]] = #llvm.di_location<{{.*}} in #[[LB1]]>
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -245,7 +245,7 @@ define void @func_loc() !dbg !3 {
}
; CHECK-DAG: #[[FILE_LOC:.+]] = loc("debug-info.ll":42:0)
; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #{{.*}}, scope = #{{.*}}, name = "func_loc", file = #{{.*}}, line = 42, subprogramFlags = Definition>
-; CHECK-DAG: #{{.+}} = #llvm.di_loc<#[[FILE_LOC]] in #[[SP]]>
+; CHECK-DAG: #{{.+}} = #llvm.di_location<#[[FILE_LOC]] in #[[SP]]>
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -286,8 +286,8 @@ define void @intrinsic(i64 %0, ptr %1) {
ret void
}
-; CHECK: #[[LOC1]] = #llvm.di_loc<{{.*}} in #[[$SP]]>
-; CHECK: #[[LOC0]] = #llvm.di_loc<{{.*}} in #[[$SP]]>
+; CHECK: #[[LOC1]] = #llvm.di_location<{{.*}} in #[[$SP]]>
+; CHECK: #[[LOC0]] = #llvm.di_location<{{.*}} in #[[$SP]]>
declare void @llvm.dbg.value(metadata, metadata, metadata)
declare void @llvm.dbg.declare(metadata, metadata, metadata)
@@ -321,7 +321,7 @@ define void @class_method() {
; CHECK-DAG: #[[COMP_PTR:.+]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, baseType = #[[COMP]], sizeInBits = 64, flags = "Artificial|ObjectPointer">
; CHECK-DAG: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type<types = #{{.*}}, #[[COMP_PTR]]>
; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram<recId = [[REC_ID]], id = [[SP_ID:.+]], compileUnit = #{{.*}}, scope = #[[COMP]], name = "class_method", file = #{{.*}}, subprogramFlags = Definition, type = #[[SP_TYPE]]>
-; CHECK-DAG: #[[LOC]] = #llvm.di_loc<{{.*}} in #[[SP]]>
+; CHECK-DAG: #[[LOC]] = #llvm.di_location<{{.*}} in #[[SP]]>
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -551,7 +551,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
; // -----
; CHECK: #[[SUBPROGRAM:.*]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #{{.*}}, scope = #{{.*}}, file = #{{.*}}, subprogramFlags = Definition>
-; CHECK: #[[FUNC_LOC:.*]] = #llvm.di_loc<{{.*}} in #[[SUBPROGRAM]]>
+; CHECK: #[[FUNC_LOC:.*]] = #llvm.di_location<{{.*}} in #[[SUBPROGRAM]]>
define void @noname_subprogram(ptr %arg) !dbg !8 {
ret void
}
@@ -618,7 +618,7 @@ declare !dbg !1 void @declaration()
; CHECK-NOT: id = distinct
; CHECK-NOT: subprogramFlags =
; CHECK-SAME: >
-; CHECK: #{{.+}} = #llvm.di_loc<{{.*}} in #[[SP]]>
+; CHECK: #{{.+}} = #llvm.di_location<{{.*}} in #[[SP]]>
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"Debug Info Version", i32 3}
More information about the Mlir-commits
mailing list