[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