[llvm] [DebugInfo] Add DILayerLoc/DILayerLocList and DILocation irlayers operand (PR #215666)

Eric Christopher via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 14 13:59:10 PDT 2026


================
@@ -1511,4 +1512,404 @@ TEST(DIBuilder, DynamicOffsetAndSize) {
   EXPECT_EQ(Field->getRawSizeInBits(), Len);
 }
 
+// Tests for DebugLoc with intermediate location support.
+
+TEST(DebugLocTest, IntermediateLocBasics) {
+  LLVMContext Ctx;
+  auto M = std::make_unique<Module>("MyModule", Ctx);
+  DIBuilder DIB(*M);
+  DIFile *F = DIB.createFile("source.cu", "/");
+  DIFile *IntF = DIB.createFile("intermediate.mlir", "/");
+  DICompileUnit *CU =
+      DIB.createCompileUnit(dwarf::DW_LANG_C, F, "test", false, "", 0);
+  DISubprogram *SP =
+      DIB.createFunction(CU, "foo", "", F, 1, DIB.createSubroutineType({}), 1,
+                         DINode::FlagZero, DISubprogram::SPFlagDefinition);
+
+  // Build a layered DILocation: a source coordinate plus one TileIR layer that
+  // hangs off the DILocation's typed `irlayers` operand.
+  MDString *Kind = MDString::get(Ctx, "TileIR");
+  DILayerLoc *Layer = DILayerLoc::get(Ctx, Kind, IntF, 100, 1);
+  DILayerLocList *Layers = DILayerLocList::get(Ctx, {Layer});
+  DILocation *Loc =
+      DILocation::get(Ctx, 10, 5, SP, /*InlinedAt=*/nullptr,
+                      /*ImplicitCode=*/false, /*AtomGroup=*/0, /*AtomRank=*/0,
+                      /*IRLayers=*/Layers);
+
+  DebugLoc DL(Loc);
+  EXPECT_TRUE((bool)DL);
+  EXPECT_EQ(DL.get(), Loc);
+  EXPECT_EQ(DL.getLine(), 10u);
+  EXPECT_EQ(DL.getCol(), 5u);
+
+  // The layer list is reachable through both DebugLoc and DILocation.
+  EXPECT_EQ(DL.getRawIRLayers(), Layers);
+  ASSERT_EQ(Loc->getIRLayers(), Layers);
+  ASSERT_EQ(Loc->getNumLayers(), 1u);
+  DILayerLoc *L0 = Loc->getLayer(0);
+  ASSERT_NE(L0, nullptr);
+  EXPECT_EQ(L0->getKind(), "TileIR");
+  EXPECT_EQ(L0->getFile(), IntF);
+  EXPECT_EQ(L0->getLine(), 100u);
+  EXPECT_EQ(L0->getColumn(), 1u);
+}
+
+TEST(DebugLocTest, IntermediateLocWithAndWithout) {
+  LLVMContext Ctx;
+  auto M = std::make_unique<Module>("MyModule", Ctx);
+  DIBuilder DIB(*M);
+  DIFile *F = DIB.createFile("source.cu", "/");
+  DIFile *IntF = DIB.createFile("intermediate.mlir", "/");
+  DICompileUnit *CU =
+      DIB.createCompileUnit(dwarf::DW_LANG_C, F, "test", false, "", 0);
+  DISubprogram *SP =
+      DIB.createFunction(CU, "foo", "", F, 1, DIB.createSubroutineType({}), 1,
+                         DINode::FlagZero, DISubprogram::SPFlagDefinition);
+
+  // A source-only DILocation has no layers.
+  DILocation *SourceLoc = DILocation::get(Ctx, 10, 5, SP);
+  DebugLoc DLSourceOnly(SourceLoc);
+  EXPECT_EQ(SourceLoc->getRawIRLayers(), nullptr);
+  EXPECT_EQ(SourceLoc->getIRLayers(), nullptr);
+  EXPECT_EQ(SourceLoc->getNumLayers(), 0u);
+  EXPECT_EQ(DLSourceOnly.getRawIRLayers(), nullptr);
+  EXPECT_EQ(DLSourceOnly.get(), SourceLoc);
+
+  // A layered DILocation returns its list.
+  MDString *Kind = MDString::get(Ctx, "TileIR");
+  DILayerLoc *Layer = DILayerLoc::get(Ctx, Kind, IntF, 100, 1);
+  DILayerLocList *Layers = DILayerLocList::get(Ctx, {Layer});
+  DILocation *LayeredLoc =
+      DILocation::get(Ctx, 10, 5, SP, /*InlinedAt=*/nullptr,
+                      /*ImplicitCode=*/false,
+                      /*AtomGroup=*/0, /*AtomRank=*/0,
+                      /*IRLayers=*/Layers);
+  DebugLoc DLWithInt(LayeredLoc);
+  EXPECT_EQ(DLWithInt.getRawIRLayers(), Layers);
+  EXPECT_EQ(LayeredLoc->getIRLayers(), Layers);
+  ASSERT_EQ(LayeredLoc->getNumLayers(), 1u);
+  EXPECT_EQ(LayeredLoc->getLayer(0)->getKind(), "TileIR");
+}
+
+TEST(DebugLocTest, IntermediateLocEquality) {
+  LLVMContext Ctx;
+  auto M = std::make_unique<Module>("MyModule", Ctx);
+  DIBuilder DIB(*M);
+  DIFile *F = DIB.createFile("source.cu", "/");
+  DIFile *IntF = DIB.createFile("intermediate.mlir", "/");
+  DICompileUnit *CU =
+      DIB.createCompileUnit(dwarf::DW_LANG_C, F, "test", false, "", 0);
+  DISubprogram *SP =
+      DIB.createFunction(CU, "foo", "", F, 1, DIB.createSubroutineType({}), 1,
+                         DINode::FlagZero, DISubprogram::SPFlagDefinition);
+
+  MDString *Kind = MDString::get(Ctx, "TileIR");
+  DILayerLoc *LayerA = DILayerLoc::get(Ctx, Kind, IntF, 100, 1);
+  // Differs from LayerA in a single field (column only) -- a minimal structural
+  // change must still uniquify to a distinct node, so DL1 and DL3 differ.
+  DILayerLoc *LayerB = DILayerLoc::get(Ctx, Kind, IntF, 100, 2);
+  DILayerLocList *ListA = DILayerLocList::get(Ctx, {LayerA});
+  // A structurally-identical list uniques to the same node.
+  DILayerLocList *ListA2 = DILayerLocList::get(Ctx, {LayerA});
+  DILayerLocList *ListB = DILayerLocList::get(Ctx, {LayerB});
+  EXPECT_EQ(ListA, ListA2);
+  EXPECT_NE(ListA, ListB);
+
+  auto Layered = [&](DILayerLocList *L) {
+    return DILocation::get(Ctx, 10, 5, SP, /*InlinedAt=*/nullptr,
+                           /*ImplicitCode=*/false, /*AtomGroup=*/0,
+                           /*AtomRank=*/0, /*IRLayers=*/L);
+  };
+  DebugLoc DL1(Layered(ListA));
+  // A *distinct* location with the same fields and the same (uniqued) layer
+  // list, so isSameSourceLocation cannot short-circuit on pointer identity and
+  // must actually run the structural getRawIRLayers() comparison.
----------------
echristo wrote:

You sure it's running them, for some reason I thought I saw it skipped?

https://github.com/llvm/llvm-project/pull/215666


More information about the llvm-commits mailing list