[MLIR][LLVM] Add variant part debug info support (#195321)

#### Summary

This PR extends the MLIR LLVM dialect debug-info attributes to represent
DWARF variant parts, discriminators, and per-alternative discriminator
values.

The change adds `identifier` and `discriminator` support to
`DICompositeTypeAttr`, allowing MLIR to model `DW_TAG_variant_part`
metadata that LLVM IR already supports. It also broadens
`DIDerivedTypeAttr`'s `extraData` field from `DINodeAttr` to a verified
polymorphic `Attribute`, supporting both debug-info nodes and integer
constants used by variant alternatives.

#### Details

- Add `identifier` and `discriminator` fields to `DICompositeTypeAttr`,
bytecode serialization, LLVM IR import/export, C API bindings, and Flang
call sites.
- Change `DIDerivedTypeAttr.extraData` to accept either `DINodeAttr` or
`IntegerAttr`, with verifier coverage for invalid attribute kinds.
- Preserve integer bit width when importing
`ConstantAsMetadata(ConstantInt)` into MLIR.
- Add parse/print, verifier, LLVM IR import/export, and C API test
coverage for variant-part debug info.

---------

Co-authored-by: Tobias Gysi <tobias.gysi@nextsilicon.com>
This commit is contained in:
jiel-nv 2026-05-04 11:43:12 -07:00 committed by GitHub
parent 7c97178488
commit d7693e331c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 188 additions and 27 deletions

View file

@ -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(

View file

@ -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);

View file

@ -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<"Attribute">:$extraData
);
let assemblyFormat = "`<` struct(params) `>`";
let genVerifyDecl = 1;
// Generate mnemonic alias for the attribute.
let genMnemonicAlias = 1;

View file

@ -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
)>;
//===----------------------------------------------------------------------===//

View file

@ -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) {

View file

@ -204,6 +204,21 @@ 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 +335,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, {}, {},
{}, {}, {});
{}, {}, {}, {}, {});
}
//===----------------------------------------------------------------------===//

View file

@ -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,19 @@ 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()),

View file

@ -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,14 +236,27 @@ 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()),
translate(attr.getBaseType()), attr.getSizeInBits(),
attr.getAlignInBits(), attr.getOffsetInBits(),
attr.getDwarfAddressSpace(), /*PtrAuthData=*/std::nullopt,
/*Flags=*/static_cast<llvm::DINode::DIFlags>(attr.getFlags()),
translate(attr.getExtraData()));
/*Flags=*/static_cast<llvm::DINode::DIFlags>(attr.getFlags()), extraData);
}
llvm::DIStringType *DebugTranslation::translateImpl(DIStringTypeAttr attr) {

View file

@ -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) {

View file

@ -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]]>

View file

@ -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}}

View file

@ -986,3 +986,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)

View file

@ -818,3 +818,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)