[Mlir-commits] [flang] [mlir] [MLIR][LLVM] Add variant part debug info support (PR #195321)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Sun May 3 00:53:56 PDT 2026


https://github.com/jiel-nv updated https://github.com/llvm/llvm-project/pull/195321

>From 937c528c4df9f2bcc036451e562b7fd16067da1c Mon Sep 17 00:00:00 2001
From: jiel-nv <jiel at nvidia.com>
Date: Thu, 30 Apr 2026 08:39:46 -0700
Subject: [PATCH 1/2] [MLIR][LLVM] Add variant part debug info support

---
 .../Transforms/DebugTypeGenerator.cpp         | 24 ++++++++-----
 mlir/include/mlir-c/Dialect/LLVM.h            |  3 +-
 .../mlir/Dialect/LLVMIR/LLVMAttrDefs.td       | 10 ++++--
 .../Dialect/LLVMIR/LLVMDialectBytecode.td     |  4 ++-
 mlir/lib/CAPI/Dialect/LLVM.cpp                |  7 ++--
 mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp      | 21 +++++++++--
 mlir/lib/Target/LLVMIR/DebugImporter.cpp      | 20 +++++++++--
 mlir/lib/Target/LLVMIR/DebugTranslation.cpp   | 23 ++++++++++--
 mlir/test/CAPI/llvm.c                         |  7 +++-
 mlir/test/Dialect/LLVMIR/debuginfo.mlir       | 35 +++++++++++++++++--
 mlir/test/Dialect/LLVMIR/types-invalid.mlir   |  7 ++++
 mlir/test/Target/LLVMIR/Import/debug-info.ll  | 28 +++++++++++++++
 mlir/test/Target/LLVMIR/llvmir-debug.mlir     | 29 +++++++++++++++
 13 files changed, 192 insertions(+), 26 deletions(-)

diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index da7a513315a4e..f6e18c5b27391 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -187,7 +187,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
         /*file=*/nullptr, /*line=*/0, /*scope=*/nullptr, elemTy,
         mlir::LLVM::DIFlags::Zero, /*sizeInBits=*/0, /*alignInBits=*/0,
         dataLocation, rank, /*allocated=*/nullptr,
-        /*associated=*/nullptr, elements);
+        /*associated=*/nullptr, /*identifier=*/nullptr,
+        /*discriminator=*/nullptr, elements);
   }
 
   addOp(llvm::dwarf::DW_OP_push_object_address, {});
@@ -264,7 +265,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
       context, llvm::dwarf::DW_TAG_array_type, /*name=*/nullptr,
       /*file=*/nullptr, /*line=*/0, /*scope=*/nullptr, elemTy,
       mlir::LLVM::DIFlags::Zero, /*sizeInBits=*/0, /*alignInBits=*/0,
-      dataLocation, /*rank=*/nullptr, allocated, associated, elements);
+      dataLocation, /*rank=*/nullptr, allocated, associated,
+      /*identifier=*/nullptr, /*discriminator=*/nullptr, elements);
 }
 
 std::pair<std::uint64_t, unsigned short>
@@ -398,7 +400,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
       mlir::StringAttr::get(context, ""), fileAttr, /*line=*/0, scope,
       /*baseType=*/nullptr, mlir::LLVM::DIFlags::Zero, /*sizeInBits=*/0,
       /*alignInBits=*/0, /*dataLocation=*/nullptr, /*rank=*/nullptr,
-      /*allocated=*/nullptr, /*associated=*/nullptr, elements);
+      /*allocated=*/nullptr, /*associated=*/nullptr, /*identifier=*/nullptr,
+      /*discriminator=*/nullptr, elements);
   DerivedTypeCache::ActiveLevels nestedRecursions =
       derivedTypeCache.startTranslating(Ty, placeHolder);
 
@@ -438,7 +441,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
           convertType(seqTy.getEleTy(), fileAttr, scope, declOp),
           mlir::LLVM::DIFlags::Zero, /*sizeInBits=*/0, /*alignInBits=*/0,
           /*dataLocation=*/nullptr, /*rank=*/nullptr,
-          /*allocated=*/nullptr, /*associated=*/nullptr, arrayElements);
+          /*allocated=*/nullptr, /*associated=*/nullptr,
+          /*identifier=*/nullptr, /*discriminator=*/nullptr, arrayElements);
     } else
       elemTy = convertType(fieldTy, fileAttr, scope, /*declOp=*/nullptr);
     offset = llvm::alignTo(offset, byteAlign);
@@ -459,7 +463,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
       mlir::StringAttr::get(context, sourceName.name), fileAttr, line, scope,
       /*baseType=*/nullptr, mlir::LLVM::DIFlags::Zero, offset * 8,
       /*alignInBits=*/0, /*dataLocation=*/nullptr, /*rank=*/nullptr,
-      /*allocated=*/nullptr, /*associated=*/nullptr, elements);
+      /*allocated=*/nullptr, /*associated=*/nullptr, /*identifier=*/nullptr,
+      /*discriminator=*/nullptr, elements);
 
   derivedTypeCache.finalize(Ty, finalAttr, std::move(nestedRecursions));
 
@@ -503,7 +508,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertTupleType(
       mlir::StringAttr::get(context, ""), fileAttr, /*line=*/0, scope,
       /*baseType=*/nullptr, mlir::LLVM::DIFlags::Zero, offset * 8,
       /*alignInBits=*/0, /*dataLocation=*/nullptr, /*rank=*/nullptr,
-      /*allocated=*/nullptr, /*associated=*/nullptr, elements);
+      /*allocated=*/nullptr, /*associated=*/nullptr, /*identifier=*/nullptr,
+      /*discriminator=*/nullptr, elements);
   derivedTypeCache.finalize(Ty, typeAttr, std::move(nestedRecursions));
   return typeAttr;
 }
@@ -565,7 +571,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
       /*file=*/nullptr, /*line=*/0, /*scope=*/nullptr, elemTy,
       mlir::LLVM::DIFlags::Zero, /*sizeInBits=*/0, /*alignInBits=*/0,
       /*dataLocation=*/nullptr, /*rank=*/nullptr, /*allocated=*/nullptr,
-      /*associated=*/nullptr, elements);
+      /*associated=*/nullptr, /*identifier=*/nullptr,
+      /*discriminator=*/nullptr, elements);
 }
 
 mlir::LLVM::DITypeAttr DebugTypeGenerator::convertVectorType(
@@ -598,7 +605,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertVectorType(
       /*file=*/nullptr, /*line=*/0, /*scope=*/nullptr, elemTy,
       mlir::LLVM::DIFlags::Vector, sizeInBits, /*alignInBits=*/0,
       /*dataLocation=*/nullptr, /*rank=*/nullptr, /*allocated=*/nullptr,
-      /*associated=*/nullptr, elements);
+      /*associated=*/nullptr, /*identifier=*/nullptr,
+      /*discriminator=*/nullptr, elements);
 }
 
 mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h
index 5170f01a2f621..09d3ad198a3b2 100644
--- a/mlir/include/mlir-c/Dialect/LLVM.h
+++ b/mlir/include/mlir-c/Dialect/LLVM.h
@@ -307,7 +307,8 @@ MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDICompositeTypeAttrGet(
     MlirAttribute baseType, int64_t flags, uint64_t sizeInBits,
     uint64_t alignInBits, intptr_t nElements, MlirAttribute const *elements,
     MlirAttribute dataLocation, MlirAttribute rank, MlirAttribute allocated,
-    MlirAttribute associated);
+    MlirAttribute associated, MlirAttribute identifier,
+    MlirAttribute discriminator);
 
 MLIR_CAPI_EXPORTED MlirStringRef mlirLLVMDICompositeTypeAttrGetName(void);
 
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 22face8b9d4b0..bb958213abd2d 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -494,6 +494,8 @@ def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type",
     OptionalParameter<"DIExpressionAttr">:$rank,
     OptionalParameter<"DIExpressionAttr">:$allocated,
     OptionalParameter<"DIExpressionAttr">:$associated,
+    OptionalParameter<"StringAttr">:$identifier,
+    OptionalParameter<"DIDerivedTypeAttr">:$discriminator,
     OptionalArrayRefParameter<"DINodeAttr">:$elements
   );
   let builders = [
@@ -503,12 +505,13 @@ def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type",
       "DIFlags":$flags, "uint64_t":$sizeInBits, "uint64_t":$alignInBits,
       "DIExpressionAttr":$dataLocation, "DIExpressionAttr":$rank,
       "DIExpressionAttr":$allocated, "DIExpressionAttr":$associated,
+      "StringAttr":$identifier, "DIDerivedTypeAttr":$discriminator,
       "ArrayRef<DINodeAttr>":$elements
     ), [{
-      return $_get($_ctxt, /*recId=*/nullptr, /*isRecSelf=*/nullptr,
+      return $_get($_ctxt, /*recId=*/nullptr, /*isRecSelf=*/false,
                    tag, name, file, line, scope, baseType, flags, sizeInBits,
                    alignInBits, dataLocation, rank, allocated,
-                   associated, elements);
+                   associated, identifier, discriminator, elements);
     }]>
   ];
   let assemblyFormat = "`<` struct(params) `>`";
@@ -547,9 +550,10 @@ def LLVM_DIDerivedTypeAttr : LLVM_Attr<"DIDerivedType", "di_derived_type",
     OptionalParameter<"uint64_t">:$offsetInBits,
     OptionalParameter<"std::optional<unsigned>">:$dwarfAddressSpace,
     OptionalParameter<"DIFlags", "DIFlags::Zero">:$flags,
-    OptionalParameter<"DINodeAttr">:$extraData
+    OptionalParameter<"::mlir::Attribute">:$extraData
   );
   let assemblyFormat = "`<` struct(params) `>`";
+  let genVerifyDecl = 1;
 
   // Generate mnemonic alias for the attribute.
   let genMnemonicAlias = 1;
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
index 05b88b428102c..a5040d5104ab9 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
@@ -189,6 +189,8 @@ def DICompositeTypeAttr : DialectAttribute<(attr
   OptionalAttribute<"DIExpressionAttr">:$rank,
   OptionalAttribute<"DIExpressionAttr">:$allocated,
   OptionalAttribute<"DIExpressionAttr">:$associated,
+  OptionalAttribute<"StringAttr">:$identifier,
+  OptionalAttribute<"DIDerivedTypeAttr">:$discriminator,
   OptionalArrayRef<"DINodeAttr">:$elements
 )>;
 
@@ -209,7 +211,7 @@ def DIDerivedTypeAttr : DialectAttribute<(attr
   OptionalInt<"unsigned">:$dwarfAddressSpace,
   EnumClassFlag<"DIFlags", "getFlags()">:$_rawflags,
   LocalVar<"DIFlags", "(DIFlags)_rawflags">:$flags,
-  OptionalAttribute<"DINodeAttr">:$extraData
+  OptionalAttribute<"Attribute">:$extraData
 )>;
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index f690af2cdb8a1..6b8cac201d8bf 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -253,7 +253,8 @@ MlirAttribute mlirLLVMDICompositeTypeAttrGet(
     MlirAttribute baseType, int64_t flags, uint64_t sizeInBits,
     uint64_t alignInBits, intptr_t nElements, MlirAttribute const *elements,
     MlirAttribute dataLocation, MlirAttribute rank, MlirAttribute allocated,
-    MlirAttribute associated) {
+    MlirAttribute associated, MlirAttribute identifier,
+    MlirAttribute discriminator) {
   SmallVector<Attribute> elementsStorage;
   elementsStorage.reserve(nElements);
 
@@ -266,6 +267,8 @@ MlirAttribute mlirLLVMDICompositeTypeAttrGet(
       cast<DIExpressionAttr>(unwrap(rank)),
       cast<DIExpressionAttr>(unwrap(allocated)),
       cast<DIExpressionAttr>(unwrap(associated)),
+      cast<StringAttr>(unwrap(identifier)),
+      cast<DIDerivedTypeAttr>(unwrap(discriminator)),
       llvm::map_to_vector(unwrapList(nElements, elements, elementsStorage),
                           llvm::CastTo<DINodeAttr>)));
 }
@@ -286,7 +289,7 @@ MlirAttribute mlirLLVMDIDerivedTypeAttrGet(
       unwrap(ctx), tag, cast<StringAttr>(unwrap(name)),
       cast<DIFileAttr>(unwrap(file)), line, cast<DIScopeAttr>(unwrap(scope)),
       cast<DITypeAttr>(unwrap(baseType)), sizeInBits, alignInBits, offsetInBits,
-      addressSpace, DIFlags(flags), cast<DINodeAttr>(unwrap(extraData))));
+      addressSpace, DIFlags(flags), unwrap(extraData)));
 }
 
 MlirStringRef mlirLLVMDIDerivedTypeAttrGetName(void) {
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
index 674a406cb368b..00d2bba3f3d36 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -204,6 +204,23 @@ bool DITypeAttr::classof(Attribute attr) {
       attr);
 }
 
+//===----------------------------------------------------------------------===//
+// DIDerivedTypeAttr
+//===----------------------------------------------------------------------===//
+
+LogicalResult
+DIDerivedTypeAttr::verify(function_ref<InFlightDiagnostic()> emitError,
+                          unsigned tag, StringAttr name, DIFileAttr file,
+                          uint32_t line, DIScopeAttr scope, DITypeAttr baseType,
+                          uint64_t sizeInBits, uint32_t alignInBits,
+                          uint64_t offsetInBits,
+                          std::optional<unsigned> dwarfAddressSpace,
+                          DIFlags flags, Attribute extraData) {
+  if (extraData && !llvm::isa<DINodeAttr, IntegerAttr>(extraData))
+    return emitError() << "extraData must be a DINodeAttr or an IntegerAttr";
+  return success();
+}
+
 //===----------------------------------------------------------------------===//
 // TBAANodeAttr
 //===----------------------------------------------------------------------===//
@@ -320,14 +337,14 @@ DICompositeTypeAttr::withRecId(DistinctAttr recId) {
       getContext(), recId, getIsRecSelf(), getTag(), getName(), getFile(),
       getLine(), getScope(), getBaseType(), getFlags(), getSizeInBits(),
       getAlignInBits(), getDataLocation(), getRank(), getAllocated(),
-      getAssociated(), getElements());
+      getAssociated(), getIdentifier(), getDiscriminator(), getElements());
 }
 
 DIRecursiveTypeAttrInterface
 DICompositeTypeAttr::getRecSelf(DistinctAttr recId) {
   return DICompositeTypeAttr::get(recId.getContext(), recId, /*isRecSelf=*/true,
                                   0, {}, {}, 0, {}, {}, DIFlags(), 0, 0, {}, {},
-                                  {}, {}, {});
+                                  {}, {}, {}, {}, {});
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
index ab37c21fdacf8..b3cbe481f5983 100644
--- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -101,7 +101,9 @@ DICompositeTypeAttr DebugImporter::translateImpl(llvm::DICompositeType *node) {
       node->getAlignInBits(), translateExpression(node->getDataLocationExp()),
       translateExpression(node->getRankExp()),
       translateExpression(node->getAllocatedExp()),
-      translateExpression(node->getAssociatedExp()), elements);
+      translateExpression(node->getAssociatedExp()),
+      getStringAttrOrNull(node->getRawIdentifier()),
+      translate(node->getDiscriminator()), elements);
 }
 
 DIDerivedTypeAttr DebugImporter::translateImpl(llvm::DIDerivedType *node) {
@@ -109,8 +111,20 @@ DIDerivedTypeAttr DebugImporter::translateImpl(llvm::DIDerivedType *node) {
   DITypeAttr baseType = translate(node->getBaseType());
   if (node->getBaseType() && !baseType)
     return nullptr;
-  DINodeAttr extraData =
-      translate(dyn_cast_or_null<llvm::DINode>(node->getExtraData()));
+  llvm::Metadata *rawExtraData = node->getExtraData();
+  Attribute extraData;
+  if (auto *extraDataNode = dyn_cast_or_null<llvm::DINode>(rawExtraData)) {
+    extraData = translate(extraDataNode);
+  } else if (auto *constantAsMetadata =
+                 dyn_cast_or_null<llvm::ConstantAsMetadata>(rawExtraData)) {
+    if (auto *constantInt =
+            dyn_cast<llvm::ConstantInt>(constantAsMetadata->getValue())) {
+      const APInt &value = constantInt->getValue();
+      extraData =
+          IntegerAttr::get(IntegerType::get(context, value.getBitWidth()),
+                           value);
+    }
+  }
   return DIDerivedTypeAttr::get(
       context, node->getTag(), getStringAttrOrNull(node->getRawName()),
       translate(node->getFile()), node->getLine(), translate(node->getScope()),
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index db9bc874314bb..a69e7b5338caa 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -10,8 +10,10 @@
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 #include "llvm/ADT/SmallVectorExtras.h"
 #include "llvm/ADT/TypeSwitch.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 
@@ -225,8 +227,8 @@ DebugTranslation::translateImpl(DICompositeTypeAttr attr) {
       /*Flags=*/static_cast<llvm::DINode::DIFlags>(attr.getFlags()),
       getMDTupleOrNull(attr.getElements()),
       /*RuntimeLang=*/0, /*EnumKind*/ std::nullopt, /*VTableHolder=*/nullptr,
-      /*TemplateParams=*/nullptr, /*Identifier=*/nullptr,
-      /*Discriminator=*/nullptr,
+      /*TemplateParams=*/nullptr, getMDStringOrNull(attr.getIdentifier()),
+      translate(attr.getDiscriminator()),
       getExpressionAttrOrNull(attr.getDataLocation()),
       getExpressionAttrOrNull(attr.getAssociated()),
       getExpressionAttrOrNull(attr.getAllocated()),
@@ -234,6 +236,21 @@ DebugTranslation::translateImpl(DICompositeTypeAttr attr) {
 }
 
 llvm::DIDerivedType *DebugTranslation::translateImpl(DIDerivedTypeAttr attr) {
+  llvm::Metadata *extraData = nullptr;
+  if (Attribute extraDataAttr = attr.getExtraData()) {
+    extraData =
+        llvm::TypeSwitch<Attribute, llvm::Metadata *>(extraDataAttr)
+            .Case([&](DINodeAttr nodeAttr) { return translate(nodeAttr); })
+            .Case([&](IntegerAttr intAttr) {
+              return llvm::ConstantAsMetadata::get(
+                  llvm::ConstantInt::get(llvmCtx, intAttr.getValue()));
+            })
+            .Default([](Attribute) -> llvm::Metadata * {
+              llvm_unreachable(
+                  "verifier guarantees DINodeAttr or IntegerAttr");
+            });
+  }
+
   return llvm::DIDerivedType::get(
       llvmCtx, attr.getTag(), getMDStringOrNull(attr.getName()),
       translate(attr.getFile()), attr.getLine(), translate(attr.getScope()),
@@ -241,7 +258,7 @@ llvm::DIDerivedType *DebugTranslation::translateImpl(DIDerivedTypeAttr attr) {
       attr.getAlignInBits(), attr.getOffsetInBits(),
       attr.getDwarfAddressSpace(), /*PtrAuthData=*/std::nullopt,
       /*Flags=*/static_cast<llvm::DINode::DIFlags>(attr.getFlags()),
-      translate(attr.getExtraData()));
+      extraData);
 }
 
 llvm::DIStringType *DebugTranslation::translateImpl(DIStringTypeAttr attr) {
diff --git a/mlir/test/CAPI/llvm.c b/mlir/test/CAPI/llvm.c
index fe48ec5568168..caa29379e9fd6 100644
--- a/mlir/test/CAPI/llvm.c
+++ b/mlir/test/CAPI/llvm.c
@@ -378,10 +378,15 @@ static void testDebugInfoAttributes(MlirContext ctx) {
   // CHECK: #llvm.di_composite_type<recId = {{.*}}, isRecSelf = true>
   mlirAttributeDump(mlirLLVMDICompositeTypeAttrGetRecSelf(recId1));
 
+  MlirAttribute discriminator = mlirLLVMDIDerivedTypeAttrGet(
+      ctx, /*DW_TAG_member=*/0x0d, bar, file, 1, compile_unit, di_type, 8, 0,
+      0, MLIR_CAPI_DWARF_ADDRESS_SPACE_NULL, 0, mlirAttributeGetNull());
+
   // CHECK: #llvm.di_composite_type<{{.*}}>
   mlirAttributeDump(mlirLLVMDICompositeTypeAttrGet(
       ctx, recId1, false, 0, foo, file, 1, compile_unit, di_type, 0, 64, 8, 1,
-      &di_type, expression, expression, expression, expression));
+      &di_type, expression, expression, expression, expression, bar,
+      discriminator));
 }
 
 int main(void) {
diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir
index e9793c15a5272..21bcbcffbace7 100644
--- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir
+++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir
@@ -29,6 +29,12 @@
   sizeInBits = 32, encoding = DW_ATE_signed
 >
 
+// CHECK-DAG: #[[FLOAT1:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "float1", sizeInBits = 32, encoding = DW_ATE_float>
+#float1 = #llvm.di_basic_type<
+  tag = DW_TAG_base_type, name = "float1",
+  sizeInBits = 32, encoding = DW_ATE_float
+>
+
 // CHECK-DAG: #[[PTR0:.*]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, baseType = #[[INT0]], sizeInBits = 64, alignInBits = 32, offsetInBits = 4, extraData = #[[INT1]]>
 #ptr0 = #llvm.di_derived_type<
   tag = DW_TAG_pointer_type, baseType = #int0,
@@ -74,6 +80,31 @@
   elements = #llvm.di_subrange<count = 4>
 >
 
+// CHECK-DAG: #[[DISC:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "discriminator", baseType = #[[INT0]], flags = Artificial>
+#disc = #llvm.di_derived_type<
+  tag = DW_TAG_member, name = "discriminator", baseType = #int0,
+  flags = Artificial
+>
+
+// CHECK-DAG: #[[ELEM_INT:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "_int1", baseType = #[[INT1]], extraData = 1 : i8>
+#elemInt = #llvm.di_derived_type<
+  tag = DW_TAG_member, name = "_int1", baseType = #int1,
+  extraData = 1 : i8
+>
+
+// CHECK-DAG: #[[ELEM_FLOAT:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "_float1", baseType = #[[FLOAT1]], extraData = 2 : i8>
+#elemFloat = #llvm.di_derived_type<
+  tag = DW_TAG_member, name = "_float1", baseType = #float1,
+  extraData = 2 : i8
+>
+
+// CHECK-DAG: #[[VARIANT:.*]] = #llvm.di_composite_type<tag = DW_TAG_variant_part, name = "variant_part", identifier = "variant-id", discriminator = #[[DISC]], elements = #[[ELEM_INT]], #[[ELEM_FLOAT]]>
+#variant = #llvm.di_composite_type<
+  tag = DW_TAG_variant_part, name = "variant_part",
+  identifier = "variant-id", discriminator = #disc,
+  elements = #elemInt, #elemFloat
+>
+
 // CHECK-DAG: #[[TOPLEVEL:.*]] = #llvm.di_namespace<name = "toplevel", exportSymbols = true>
 #toplevel_namespace = #llvm.di_namespace<
   name = "toplevel", exportSymbols = true
@@ -104,9 +135,9 @@
  name = "expr_elements2", baseType = #int0, elements =
  #llvm.di_generic_subrange<count = #exp1, lowerBound = #exp2, stride = #exp3>>
 
-// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[NULL]], #[[INT0]], #[[PTR0]], #[[PTR1]], #[[PTR2]], #[[PTR3]], #[[PTR4]], #[[COMP0:.*]], #[[COMP1:.*]], #[[COMP2:.*]], #[[COMP3:.*]]>
+// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[NULL]], #[[INT0]], #[[PTR0]], #[[PTR1]], #[[PTR2]], #[[PTR3]], #[[PTR4]], #[[COMP0:.*]], #[[COMP1:.*]], #[[COMP2:.*]], #[[COMP3:.*]], #[[VARIANT]]>
 #spType0 = #llvm.di_subroutine_type<
-  callingConvention = DW_CC_normal, types = #null, #int0, #ptr0, #ptr1, #ptr2, #ptr3, #ptr4, #comp0, #comp1, #comp2, #comp3
+  callingConvention = DW_CC_normal, types = #null, #int0, #ptr0, #ptr1, #ptr2, #ptr3, #ptr4, #comp0, #comp1, #comp2, #comp3, #variant
 >
 
 // CHECK-DAG: #[[SPTYPE1:.*]] = #llvm.di_subroutine_type<types = #[[INT1]], #[[INT1]]>
diff --git a/mlir/test/Dialect/LLVMIR/types-invalid.mlir b/mlir/test/Dialect/LLVMIR/types-invalid.mlir
index 71ebe4e1b4ef1..018a82c7b259c 100644
--- a/mlir/test/Dialect/LLVMIR/types-invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/types-invalid.mlir
@@ -103,6 +103,13 @@ func.func @unexpected_type() {
 
 // -----
 
+func.func @invalid_di_derived_type_extra_data() {
+  // expected-error @+1 {{extraData must be a DINodeAttr or an IntegerAttr}}
+  "some.op"() {attr = #llvm.di_derived_type<tag = DW_TAG_member, sizeInBits = 64, extraData = "not debug info">} : () -> ()
+}
+
+// -----
+
 func.func @explicitly_opaque_struct() {
   "some.op"() : () -> !llvm.struct<"a", opaque>
   // expected-error @+1 {{identified type already used with a different body}}
diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll
index 0465f608a90cc..4ffce5296857e 100644
--- a/mlir/test/Target/LLVMIR/Import/debug-info.ll
+++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll
@@ -947,3 +947,31 @@ define void @test() !dbg !3 {
 !12 = !DIFile(filename: "cu.hpp", directory: "/build")
 !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
 !17 = !{i32 2, !"Debug Info Version", i32 3}
+
+; // -----
+
+; CHECK-DAG: #[[DISC:.+]] = #llvm.di_derived_type<{{.*}}name = "discriminator"{{.*}}flags = Artificial>
+; CHECK-DAG: #[[ELEM_INT:.+]] = #llvm.di_derived_type<{{.*}}name = "_int64"{{.*}}extraData = 1 : i8>
+; CHECK-DAG: #[[ELEM_FLOAT:.+]] = #llvm.di_derived_type<{{.*}}name = "_float64"{{.*}}extraData = 2 : i8>
+; CHECK-DAG: #llvm.di_composite_type<{{.*}}tag = DW_TAG_variant_part{{.*}}identifier = "variant-id"{{.*}}discriminator = #[[DISC]]{{.*}}elements = #[[ELEM_INT]], #[[ELEM_FLOAT]]
+
+define void @variant_part_import() !dbg !3 {
+  ret void
+}
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
+!2 = !DIFile(filename: "foo.mlir", directory: "/tmp")
+!3 = distinct !DISubprogram(name: "variant_part_import", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1, type: !4)
+!4 = !DISubroutineType(types: !5)
+!5 = !{!8}
+!6 = !DIBasicType(name: "uint8", size: 8, encoding: DW_ATE_unsigned)
+!7 = !DIDerivedType(tag: DW_TAG_member, name: "discriminator", baseType: !6, size: 8, flags: DIFlagArtificial)
+!8 = !DICompositeType(tag: DW_TAG_variant_part, name: "variant_part", file: !2, size: 64, elements: !9, identifier: "variant-id", discriminator: !7)
+!9 = !{!12, !13}
+!10 = !DIBasicType(name: "int64", size: 64, encoding: DW_ATE_signed)
+!11 = !DIBasicType(name: "float64", size: 64, encoding: DW_ATE_float)
+!12 = !DIDerivedType(tag: DW_TAG_member, name: "_int64", baseType: !10, size: 64, offset: 64, extraData: i8 1)
+!13 = !DIDerivedType(tag: DW_TAG_member, name: "_float64", baseType: !11, size: 64, offset: 64, extraData: i8 2)
diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
index 9b1dad2910dba..9de80d0341111 100644
--- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
@@ -802,3 +802,32 @@ llvm.func @fn_cu_import_cycle() {
 
 // CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module{{.*}})
 // CHECK-DAG: !DICompileUnit({{.*}}imports:
+
+// -----
+
+#di_file  = #llvm.di_file<"foo.mlir" in "/tmp">
+#di_cu    = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #di_file, isOptimized = false, emissionKind = Full>
+#di_uint8 = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "uint8", sizeInBits = 8, encoding = DW_ATE_unsigned>
+#di_int64 = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int64", sizeInBits = 64, encoding = DW_ATE_signed>
+#di_f64   = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "float64", sizeInBits = 64, encoding = DW_ATE_float>
+#di_disc  = #llvm.di_derived_type<tag = DW_TAG_member, name = "discriminator", baseType = #di_uint8, sizeInBits = 8, flags = Artificial>
+#di_arm_i = #llvm.di_derived_type<tag = DW_TAG_member, name = "_int64", baseType = #di_int64, sizeInBits = 64, offsetInBits = 64, extraData = 1 : i8>
+#di_arm_f = #llvm.di_derived_type<tag = DW_TAG_member, name = "_float64", baseType = #di_f64, sizeInBits = 64, offsetInBits = 64, extraData = 2 : i8>
+#di_vp    = #llvm.di_composite_type<tag = DW_TAG_variant_part, name = "variant_part", file = #di_file, sizeInBits = 64, identifier = "variant-id", discriminator = #di_disc, elements = #di_arm_i, #di_arm_f>
+#di_sub   = #llvm.di_subprogram<id = distinct[1]<>, compileUnit = #di_cu, scope = #di_file, name = "variant_part_emission", file = #di_file, subprogramFlags = Definition>
+#di_local = #llvm.di_local_variable<scope = #di_sub, name = "x", file = #di_file, type = #di_vp>
+#loc      = loc(fused<#di_sub>["foo.mlir":1:1])
+
+// CHECK-LABEL: define void @variant_part_emission
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_variant_part
+// CHECK-SAME: identifier: "variant-id"
+// CHECK-SAME: discriminator: ![[DISC:[0-9]+]]
+// CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "_int64"{{.*}}extraData: i8 1)
+// CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "_float64"{{.*}}extraData: i8 2)
+// CHECK: ![[DISC]] = !DIDerivedType(tag: DW_TAG_member
+// CHECK-SAME: name: "discriminator"
+// CHECK-SAME: flags: DIFlagArtificial
+llvm.func @variant_part_emission(%arg0: i32) {
+  llvm.intr.dbg.value #di_local = %arg0 : i32 loc(#loc)
+  llvm.return loc(#loc)
+} loc(#loc)

>From 65d7b1accf43912dab75c5df5125433f6d2110f9 Mon Sep 17 00:00:00 2001
From: jiel-nv <37816794+jiel-nv at users.noreply.github.com>
Date: Sun, 3 May 2026 00:53:48 -0700
Subject: [PATCH 2/2] Update mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td

Co-authored-by: Tobias Gysi <tobias.gysi at nextsilicon.com>
---
 mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index bb958213abd2d..4304371cc0a54 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -550,7 +550,7 @@ def LLVM_DIDerivedTypeAttr : LLVM_Attr<"DIDerivedType", "di_derived_type",
     OptionalParameter<"uint64_t">:$offsetInBits,
     OptionalParameter<"std::optional<unsigned>">:$dwarfAddressSpace,
     OptionalParameter<"DIFlags", "DIFlags::Zero">:$flags,
-    OptionalParameter<"::mlir::Attribute">:$extraData
+    OptionalParameter<"Attribute">:$extraData
   );
   let assemblyFormat = "`<` struct(params) `>`";
   let genVerifyDecl = 1;



More information about the Mlir-commits mailing list