[Mlir-commits] [mlir] [MLIR][LLVM] Add DILocAttr for debug locations (PR #186146)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Mar 12 08:24:19 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-llvm
Author: Alexander Yermolovich (ayermolo)
<details>
<summary>Changes</summary>
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.
---
Patch is 27.00 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/186146.diff
13 Files Affected:
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td (+27)
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td (+10)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp (+2)
- (modified) mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp (+37-36)
- (modified) mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp (+6-7)
- (modified) mlir/lib/Target/LLVMIR/DebugImporter.cpp (+22-15)
- (modified) mlir/lib/Target/LLVMIR/DebugTranslation.cpp (+22-5)
- (modified) mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp (+4)
- (modified) mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp (+18-2)
- (modified) mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir (+3-3)
- (added) mlir/test/Dialect/LLVMIR/diloc-attr.mlir (+17)
- (modified) mlir/test/Dialect/LLVMIR/invalid-call-location.mlir (+33)
- (modified) mlir/test/Target/LLVMIR/Import/debug-info.ll (+14-14)
``````````diff
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 DILocAt...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/186146
More information about the Mlir-commits
mailing list