diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp index a3e81d0dd87a..36a03ec71c0c 100644 --- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp +++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp @@ -13,6 +13,7 @@ #include "mlir/IR/Location.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopeExit.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/Metadata.h" @@ -69,11 +70,16 @@ DICompositeTypeAttr DebugImporter::translateImpl(llvm::DICompositeType *node) { // TODO: Support debug metadata with cyclic dependencies. if (llvm::is_contained(elements, nullptr)) elements.clear(); + DITypeAttr baseType = translate(node->getBaseType()); + // Arrays require a base type, otherwise the debug metadata is considered to + // be malformed. + if (node->getTag() == llvm::dwarf::DW_TAG_array_type && !baseType) + return nullptr; return DICompositeTypeAttr::get( context, node->getTag(), getStringAttrOrNull(node->getRawName()), translate(node->getFile()), node->getLine(), translate(node->getScope()), - translate(node->getBaseType()), flags.value_or(DIFlags::Zero), - node->getSizeInBits(), node->getAlignInBits(), elements); + baseType, flags.value_or(DIFlags::Zero), node->getSizeInBits(), + node->getAlignInBits(), elements); } DIDerivedTypeAttr DebugImporter::translateImpl(llvm::DIDerivedType *node) { diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll index 2c4fb2c213cf..08e60deb699d 100644 --- a/mlir/test/Target/LLVMIR/Import/debug-info.ll +++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll @@ -159,7 +159,7 @@ define void @derived_type() !dbg !3 { ; CHECK-DAG: #[[INT:.+]] = #llvm.di_basic_type ; CHECK-DAG: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/"> -; CHECK-DAG: #[[COMP1:.+]] = #llvm.di_composite_type +; CHECK-DAG: #[[COMP1:.+]] = #llvm.di_composite_type ; CHECK-DAG: #[[COMP2:.+]] = #llvm.di_composite_type<{{.*}}, file = #[[FILE]], scope = #[[FILE]], baseType = #[[INT]]> ; CHECK-DAG: #[[COMP3:.+]] = #llvm.di_composite_type<{{.*}}, flags = Vector, elements = #llvm.di_subrange> ; CHECK-DAG: #[[COMP4:.+]] = #llvm.di_composite_type<{{.*}}, flags = Vector, elements = #llvm.di_subrange> @@ -179,10 +179,10 @@ define void @composite_type() !dbg !3 { !4 = !DISubroutineType(types: !5) !5 = !{!7, !8, !9, !10, !18} !6 = !DIBasicType(name: "int") -!7 = !DICompositeType(tag: DW_TAG_array_type, name: "array1", line: 10, size: 128, align: 32) +!7 = !DICompositeType(tag: DW_TAG_array_type, name: "array1", line: 10, size: 128, align: 32, baseType: !6) !8 = !DICompositeType(tag: DW_TAG_array_type, name: "array2", file: !2, scope: !2, baseType: !6) -!9 = !DICompositeType(tag: DW_TAG_array_type, name: "array3", flags: DIFlagVector, elements: !13) -!10 = !DICompositeType(tag: DW_TAG_array_type, name: "array4", flags: DIFlagVector, elements: !14) +!9 = !DICompositeType(tag: DW_TAG_array_type, name: "array3", flags: DIFlagVector, elements: !13, baseType: !6) +!10 = !DICompositeType(tag: DW_TAG_array_type, name: "array4", flags: DIFlagVector, elements: !14, baseType: !6) !11 = !DISubrange(count: 4) !12 = !DISubrange(lowerBound: 0, upperBound: 4, stride: 1) !13 = !{!11} @@ -192,7 +192,7 @@ define void @composite_type() !dbg !3 { !15 = !DISubrange(count: !16) !16 = !DILocalVariable(scope: !3, name: "size") !17 = !{!15} -!18 = !DICompositeType(tag: DW_TAG_array_type, name: "unsupported_elements", flags: DIFlagVector, elements: !17) +!18 = !DICompositeType(tag: DW_TAG_array_type, name: "unsupported_elements", flags: DIFlagVector, elements: !17, baseType: !6) ; // ----- @@ -558,3 +558,32 @@ define void @func_in_module(ptr %arg) !dbg !8 { !2 = !DIFile(filename: "debug-info.ll", directory: "/") !8 = distinct !DISubprogram(name: "func_in_module", scope: !10, file: !2, unit: !1); !10 = !DIModule(scope: !2, name: "module", configMacros: "bar", includePath: "/", apinotes: "/", file: !2, line: 42, isDecl: true) + +; // ----- + +; Verifies that array types that have an unimportable base type are removed to +; avoid producing invalid IR. +; CHECK: #[[DI_LOCAL_VAR:.+]] = #llvm.di_local_variable< +; CHECK-NOT: type = + +; CHECK-LABEL: @array_with_cyclic_base_type +define i32 @array_with_cyclic_base_type(ptr %0) !dbg !3 { + call void @llvm.dbg.value(metadata ptr %0, metadata !4, metadata !DIExpression()), !dbg !7 + ret i32 0 +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare void @llvm.dbg.value(metadata, metadata, metadata) + + +!llvm.module.flags = !{!0} +!llvm.dbg.cu = !{!1} + +!0 = !{i32 2, !"Debug Info Version", i32 3} +!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2) +!2 = !DIFile(filename: "debug-info.ll", directory: "/") +!3 = distinct !DISubprogram(name: "func", scope: !2, file: !2, line: 46, scopeLine: 48, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !1) +!4 = !DILocalVariable(name: "op", arg: 5, scope: !3, file: !2, line: 47, type: !5) +!5 = !DICompositeType(tag: DW_TAG_array_type, size: 42, baseType: !6) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5) +!7 = !DILocation(line: 0, scope: !3)