From f61f42b9d63d3e6b1c8f45e68a31d467f3627f75 Mon Sep 17 00:00:00 2001 From: Tobias Gysi Date: Fri, 13 Jan 2023 10:14:21 +0100 Subject: [PATCH] Reland "[mlir][llvm] Add an explicit void type debug info attribute." Previously, the DISubroutineType attribute used an optional result parameter and an optional argument types array to model the subroutine signature. LLVM IR debug metadata, on the other hand, has one types list whose first entry maps to the result type. That entry may be null to model a void result type. The type list may also be entirely empty not specifying any type information. The latter is problematic since the current DISubroutineType attribute cannot express it. The revision changes DISubroutineTypeAttr to closely follow the LLVM metadata design. In particular, it uses a single types parameter array to model the subroutine signature and introduces an explicit DIVoidResultTypeAttr to model the null entries. Reviewed By: Dinistro Differential Revision: https://reviews.llvm.org/D141261 This reverts commit 81f57b6 and relands commit a960547 Fixes flang build and drop_begin on an empty array ref. --- .../Optimizer/Transforms/AddDebugFoundation.cpp | 4 +- flang/test/Transforms/debug-line-table.fir | 2 +- mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 18 +++++--- mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp | 31 ++++++++++---- mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 8 ++-- mlir/lib/Target/LLVMIR/DebugImporter.cpp | 20 +++++---- mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 20 ++++++--- mlir/lib/Target/LLVMIR/DebugTranslation.h | 1 + mlir/test/Dialect/LLVMIR/debuginfo.mlir | 49 +++++++++++++++++----- mlir/test/Dialect/LLVMIR/invalid.mlir | 6 +++ mlir/test/Target/LLVMIR/Import/debug-info.ll | 27 ++++++------ mlir/test/Target/LLVMIR/llvmir-debug.mlir | 34 +++++++++++---- 12 files changed, 154 insertions(+), 66 deletions(-) diff --git a/flang/lib/Optimizer/Transforms/AddDebugFoundation.cpp b/flang/lib/Optimizer/Transforms/AddDebugFoundation.cpp index 1d30a8d..54fcd5e 100644 --- a/flang/lib/Optimizer/Transforms/AddDebugFoundation.cpp +++ b/flang/lib/Optimizer/Transforms/AddDebugFoundation.cpp @@ -74,8 +74,8 @@ void AddDebugFoundationPass::runOnOperation() { /*encoding=*/1); mlir::LLVM::DISubroutineTypeAttr subTypeAttr = mlir::LLVM::DISubroutineTypeAttr::get( - context, llvm::dwarf::getCallingConvention("DW_CC_normal"), bT, - {bT}); + context, llvm::dwarf::getCallingConvention("DW_CC_normal"), + {bT, bT}); mlir::LLVM::DISubprogramAttr spAttr = mlir::LLVM::DISubprogramAttr::get( context, cuAttr, fileAttr, funcName, funcName, fileAttr, /*line=*/1, /*scopeline=*/1, mlir::LLVM::DISubprogramFlags::Definition, diff --git a/flang/test/Transforms/debug-line-table.fir b/flang/test/Transforms/debug-line-table.fir index ff78b4c..fa59aeb 100644 --- a/flang/test/Transforms/debug-line-table.fir +++ b/flang/test/Transforms/debug-line-table.fir @@ -19,6 +19,6 @@ module attributes { fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.dat // CHECK: #[[MODULE_LOC]] = loc("[[DIR_NAME]]/[[FILE_NAME]]":1:1) // CHECK: #[[SB_LOC]] = loc("./simple.f90":2:1) // CHECK: #di_compile_unit = #llvm.di_compile_unit -// CHECK: #di_subroutine_type = #llvm.di_subroutine_type +// CHECK: #di_subroutine_type = #llvm.di_subroutine_type // CHECK: #di_subprogram = #llvm.di_subprogram // CHECK: #[[FUSED_SB_LOC]] = loc(fused<#di_subprogram>[#[[SB_LOC]]]) diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index f38558c..733d573 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -123,6 +123,15 @@ def LLVM_DITagParameter : LLVM_DIParameter< >; //===----------------------------------------------------------------------===// +// DIVoidResultTypeAttr +//===----------------------------------------------------------------------===// + +def LLVM_DIVoidResultTypeAttr : LLVM_Attr<"DIVoidResultType", "di_void_result_type", + /*traits=*/[], "DITypeAttr"> { + let parameters = (ins); +} + +//===----------------------------------------------------------------------===// // DIBasicTypeAttr //===----------------------------------------------------------------------===// @@ -353,16 +362,15 @@ def LLVM_DISubroutineTypeAttr : LLVM_Attr<"DISubroutineType", "di_subroutine_typ ], "DITypeAttr"> { let parameters = (ins LLVM_DICallingConventionParameter:$callingConvention, - OptionalParameter<"DITypeAttr">:$resultType, - OptionalArrayRefParameter<"DITypeAttr">:$argumentTypes + OptionalArrayRefParameter<"DITypeAttr">:$types ); let builders = [ - TypeBuilder<(ins "DITypeAttr":$resultType, - "ArrayRef":$argumentTypes), [{ - return $_get($_ctxt, /*callingConvention=*/0, resultType, argumentTypes); + TypeBuilder<(ins "ArrayRef":$types), [{ + return $_get($_ctxt, /*callingConvention=*/0, types); }]> ]; let assemblyFormat = "`<` struct(params) `>`"; + let genVerifyDecl = 1; } #endif // LLVMIR_ATTRDEFS diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp index 2bf1cab..c74ceb9 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp @@ -41,11 +41,11 @@ void LLVMDialect::registerAttributes() { //===----------------------------------------------------------------------===// bool DINodeAttr::classof(Attribute attr) { - return llvm::isa( - attr); + return llvm::isa(attr); } //===----------------------------------------------------------------------===// @@ -63,8 +63,25 @@ bool DIScopeAttr::classof(Attribute attr) { //===----------------------------------------------------------------------===// bool DITypeAttr::classof(Attribute attr) { - return llvm::isa(attr); + return llvm::isa(attr); +} + +//===----------------------------------------------------------------------===// +// DISubroutineTypeAttr +//===----------------------------------------------------------------------===// + +LogicalResult +DISubroutineTypeAttr::verify(function_ref emitError, + unsigned int callingConventions, + ArrayRef types) { + ArrayRef argumentTypes = + types.empty() ? types : types.drop_front(); + if (llvm::any_of(argumentTypes, [](DITypeAttr type) { + return type.isa(); + })) + return emitError() << "expected subroutine to have non-void argument types"; + return success(); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp index 09b118d..327d4be 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -2825,10 +2825,10 @@ struct LLVMOpAsmDialectInterface : public OpAsmDialectInterface { AliasResult getAlias(Attribute attr, raw_ostream &os) const override { return TypeSwitch(attr) - .Case([&](auto attr) { + .Case([&](auto attr) { os << decltype(attr)::getMnemonic(); return AliasResult::OverridableAlias; }) diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp index dac737d..343ec92 100644 --- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp +++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp @@ -129,15 +129,19 @@ DISubrangeAttr DebugImporter::translateImpl(llvm::DISubrange *node) { DISubroutineTypeAttr DebugImporter::translateImpl(llvm::DISubroutineType *node) { - // Separate the result type since it is null for void functions. - DITypeAttr resultType = translate(*node->getTypeArray().begin()); - SmallVector argumentTypes; - for (llvm::DIType *type : llvm::drop_begin(node->getTypeArray())) { - assert(type && "expected a non-null argument type"); - argumentTypes.push_back(translate(type)); + SmallVector types; + for (llvm::DIType *type : node->getTypeArray()) { + if (!type) { + // A nullptr entry at the beginning of the subroutine types list models a + // void result type. Translate the nullptr to an explicit + // DIVoidResultTypeAttr since the attribute list cannot contain a nullptr + // entry. + types.push_back(DIVoidResultTypeAttr::get(context)); + continue; + } + types.push_back(translate(type)); } - return DISubroutineTypeAttr::get(context, node->getCC(), resultType, - argumentTypes); + return DISubroutineTypeAttr::get(context, node->getCC(), types); } DITypeAttr DebugImporter::translateImpl(llvm::DIType *node) { diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp index 2423e95..96f8880 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -88,6 +88,14 @@ void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) { // Attributes //===----------------------------------------------------------------------===// +llvm::DIType *DebugTranslation::translateImpl(DIVoidResultTypeAttr attr) { + // A DIVoidResultTypeAttr at the beginning of the subroutine types list models + // a void result type. Translate the explicit DIVoidResultTypeAttr to a + // nullptr since LLVM IR metadata does not have an explicit void result type + // representation. + return nullptr; +} + llvm::DIBasicType *DebugTranslation::translateImpl(DIBasicTypeAttr attr) { return llvm::DIBasicType::get( llvmCtx, attr.getTag(), attr.getName(), attr.getSizeInBits(), @@ -201,8 +209,8 @@ llvm::DISubrange *DebugTranslation::translateImpl(DISubrangeAttr attr) { llvm::DISubroutineType * DebugTranslation::translateImpl(DISubroutineTypeAttr attr) { // Concatenate the result and argument types into a single array. - SmallVector types = {translate(attr.getResultType())}; - for (DITypeAttr type : attr.getArgumentTypes()) + SmallVector types; + for (DITypeAttr type : attr.getTypes()) types.push_back(translate(type)); return llvm::DISubroutineType::get( llvmCtx, llvm::DINode::FlagZero, attr.getCallingConvention(), @@ -222,10 +230,10 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) { llvm::DINode *node = TypeSwitch(attr) - .Case( + .Case( [&](auto attr) { return translateImpl(attr); }); attrToNode.insert({attr, node}); return node; diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h index 79f1326..f9c87ba 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.h +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h @@ -61,6 +61,7 @@ private: llvm::DIFile *translateFile(StringRef fileName); /// Translate the given attribute to the corresponding llvm debug metadata. + llvm::DIType *translateImpl(DIVoidResultTypeAttr attr); llvm::DIBasicType *translateImpl(DIBasicTypeAttr attr); llvm::DICompileUnit *translateImpl(DICompileUnitAttr attr); llvm::DICompositeType *translateImpl(DICompositeTypeAttr attr); diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir index ff03643..4e13c5e 100644 --- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir +++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir @@ -9,6 +9,9 @@ isOptimized = true, emissionKind = Full > +// CHECK-DAG: #[[VOID:.*]] = #llvm.di_void_result_type +#void = #llvm.di_void_result_type + // CHECK-DAG: #[[INT0:.*]] = #llvm.di_basic_type #int0 = #llvm.di_basic_type< // Omit the optional sizeInBits and encoding parameters. @@ -53,15 +56,21 @@ flags = "TypePassByReference|NonTrivial" > -// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type +// CHECK-DAG: #[[SPTYPE0:.*]] = #llvm.di_subroutine_type #spType0 = #llvm.di_subroutine_type< - callingConvention = DW_CC_normal, argumentTypes = #int0, #ptr0, #ptr1, #comp0, #comp1, #comp2 + callingConvention = DW_CC_normal, types = #void, #int0, #ptr0, #ptr1, #comp0, #comp1, #comp2 > -// CHECK-DAG: #[[SPTYPE1:.*]] = #llvm.di_subroutine_type +// CHECK-DAG: #[[SPTYPE1:.*]] = #llvm.di_subroutine_type #spType1 = #llvm.di_subroutine_type< // Omit the optional callingConvention parameter. - resultType = #int1, argumentTypes = #int1 + types = #int1, #int1 +> + +// CHECK-DAG: #[[SPTYPE2:.*]] = #llvm.di_subroutine_type +#spType2 = #llvm.di_subroutine_type< + // Omit the optional types parameter array. + callingConvention = DW_CC_normal > // CHECK-DAG: #[[SP0:.*]] = #llvm.di_subprogram @@ -77,22 +86,38 @@ file = #file, subprogramFlags = "Definition", type = #spType1 > +// CHECK-DAG: #[[SP2:.*]] = #llvm.di_subprogram +#sp2 = #llvm.di_subprogram< + // Omit the optional linkageName parameter. + compileUnit = #cu, scope = #file, name = "value", + file = #file, subprogramFlags = "Definition", type = #spType2 +> + // CHECK-DAG: #[[BLOCK0:.*]] = #llvm.di_lexical_block #block0 = #llvm.di_lexical_block // CHECK-DAG: #[[BLOCK1:.*]] = #llvm.di_lexical_block #block1 = #llvm.di_lexical_block +// CHECK-DAG: #[[BLOCK2:.*]] = #llvm.di_lexical_block +#block2 = #llvm.di_lexical_block + // CHECK-DAG: #[[VAR0:.*]] = #llvm.di_local_variable #var0 = #llvm.di_local_variable< scope = #block0, name = "alloc", file = #file, line = 6, arg = 1, alignInBits = 32, type = #int0 > -// CHECK-DAG: #[[VAR1:.*]] = #llvm.di_local_variable +// CHECK-DAG: #[[VAR1:.*]] = #llvm.di_local_variable #var1 = #llvm.di_local_variable< // Omit the optional parameters. - scope = #block1, name = "arg" + scope = #block1, name = "arg1" +> + +// CHECK-DAG: #[[VAR2:.*]] = #llvm.di_local_variable +#var2 = #llvm.di_local_variable< + // Omit the optional parameters. + scope = #block2, name = "arg2" > // CHECK: llvm.func @addr(%[[ARG:.*]]: i64) @@ -108,9 +133,11 @@ llvm.func @addr(%arg: i64) { llvm.return } -// CHECK: llvm.func @value(%[[ARG:.*]]: i32) -llvm.func @value(%arg: i32) -> i32 { - // CHECK: llvm.intr.dbg.value #[[VAR1]] = %[[ARG]] - llvm.intr.dbg.value #var1 = %arg : i32 - llvm.return %arg : i32 +// CHECK: llvm.func @value(%[[ARG1:.*]]: i32, %[[ARG2:.*]]: i32) +llvm.func @value(%arg1: i32, %arg2: i32) { + // CHECK: llvm.intr.dbg.value #[[VAR1]] = %[[ARG1]] + llvm.intr.dbg.value #var1 = %arg1 : i32 + // CHECK: llvm.intr.dbg.value #[[VAR2]] = %[[ARG2]] + llvm.intr.dbg.value #var2 = %arg2 : i32 + llvm.return } diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir index 1593906..7d130b2 100644 --- a/mlir/test/Dialect/LLVMIR/invalid.mlir +++ b/mlir/test/Dialect/LLVMIR/invalid.mlir @@ -1386,3 +1386,9 @@ func.func @extract_scalable_from_fixed_length_vector(%arg0 : vector<16xf32>) { // expected-error@+1 {{op failed to verify that it is not extracting scalable from fixed-length vectors.}} %0 = llvm.intr.vector.extract %arg0[0] : vector<[8]xf32> from vector<16xf32> } + +// ----- + +#void = #llvm.di_void_result_type +// expected-error@below {{expected subroutine to have non-void argument types}} +#void_argument_type = #llvm.di_subroutine_type diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll index 4a8a43b..2888b7a 100644 --- a/mlir/test/Target/LLVMIR/Import/debug-info.ll +++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll @@ -112,9 +112,10 @@ define i32 @lexical_block_file(i32 %arg1) { ; // ----- -; CHECK: #[[INT1:.+]] = #llvm.di_basic_type -; CHECK: #[[INT2:.+]] = #llvm.di_basic_type -; CHECK: #llvm.di_subroutine_type +; CHECK-DAG: #[[VOID:.+]] = #llvm.di_void_result_type +; CHECK-DAG: #[[INT1:.+]] = #llvm.di_basic_type +; CHECK-DAG: #[[INT2:.+]] = #llvm.di_basic_type +; CHECK-DAG: #llvm.di_subroutine_type define void @basic_type() !dbg !3 { ret void @@ -136,7 +137,7 @@ define void @basic_type() !dbg !3 { ; CHECK: #[[INT:.+]] = #llvm.di_basic_type ; CHECK: #[[PTR1:.+]] = #llvm.di_derived_type ; CHECK: #[[PTR2:.+]] = #llvm.di_derived_type -; CHECK: #llvm.di_subroutine_type +; CHECK: #llvm.di_subroutine_type define void @derived_type() !dbg !3 { ret void @@ -149,7 +150,7 @@ define void @derived_type() !dbg !3 { !2 = !DIFile(filename: "debug-info.ll", directory: "/") !3 = distinct !DISubprogram(name: "derived_type", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1, type: !4) !4 = !DISubroutineType(types: !5) -!5 = !{null, !7, !8} +!5 = !{!7, !8} !6 = !DIBasicType(name: "int") !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6) !8 = !DIDerivedType(name: "mypointer", tag: DW_TAG_pointer_type, baseType: !6, size: 64, align: 32, offset: 4) @@ -162,7 +163,7 @@ define void @derived_type() !dbg !3 { ; 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> -; CHECK-DAG: #llvm.di_subroutine_type +; CHECK-DAG: #llvm.di_subroutine_type define void @composite_type() !dbg !3 { ret void @@ -175,7 +176,7 @@ define void @composite_type() !dbg !3 { !2 = !DIFile(filename: "debug-info.ll", directory: "/") !3 = distinct !DISubprogram(name: "composite_type", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1, type: !4) !4 = !DISubroutineType(types: !5) -!5 = !{null, !7, !8, !9, !10} +!5 = !{!7, !8, !9, !10} !6 = !DIBasicType(name: "int") !7 = !DICompositeType(tag: DW_TAG_array_type, name: "array1", line: 10, size: 128, align: 32) !8 = !DICompositeType(tag: DW_TAG_array_type, name: "array2", file: !2, scope: !2, baseType: !6) @@ -188,11 +189,11 @@ define void @composite_type() !dbg !3 { ; // ----- -; CHECK: #[[INT:.+]] = #llvm.di_basic_type -; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/"> -; CHECK: #[[CU:.+]] = #llvm.di_compile_unit -; CHECK: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type -; CHECK: #[[SP:.+]] = #llvm.di_subprogram +; CHECK-DAG: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/"> +; CHECK-DAG: #[[CU:.+]] = #llvm.di_compile_unit +; Verify an empty subroutine types list is supported. +; CHECK-DAG: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type +; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram define void @subprogram() !dbg !3 { ret void @@ -205,7 +206,7 @@ define void @subprogram() !dbg !3 { !2 = !DIFile(filename: "debug-info.ll", directory: "/") !3 = distinct !DISubprogram(name: "subprogram", linkageName: "subprogram", scope: !2, file: !2, line: 42, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1, type: !4) !4 = !DISubroutineType(cc: DW_CC_normal, types: !5) -!5 = !{!6, !6} +!5 = !{} !6 = !DIBasicType(name: "int") ; // ----- diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir index 434207e..50d18eb 100644 --- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir @@ -48,24 +48,31 @@ llvm.func @func_no_debug() { baseType = #si64, flags = Vector, elements = #llvm.di_subrange > -#spType = #llvm.di_subroutine_type -#sp = #llvm.di_subprogram< +#void = #llvm.di_void_result_type +#spType0 = #llvm.di_subroutine_type +#sp0 = #llvm.di_subprogram< compileUnit = #cu, scope = #file, name = "func_with_debug", linkageName = "func_with_debug", - file = #file, line = 3, scopeLine = 3, subprogramFlags = "Definition|Optimized", type = #spType + file = #file, line = 3, scopeLine = 3, subprogramFlags = "Definition|Optimized", type = #spType0 > #calleeType = #llvm.di_subroutine_type< - // Omit the optional callingConvention parameter but specify a result type. - resultType = #si64, argumentTypes = #si64> + // Omit the optional callingConvention parameter. + types = #si64, #si64> #callee = #llvm.di_subprogram< // Omit the optional linkageName, line, and scopeLine parameters. compileUnit = #cu, scope = #composite, name = "callee", file = #file, subprogramFlags = "Definition", type = #calleeType > -#fileScope = #llvm.di_lexical_block_file -#blockScope = #llvm.di_lexical_block +#fileScope = #llvm.di_lexical_block_file +#blockScope = #llvm.di_lexical_block #variable = #llvm.di_local_variable #variableAddr = #llvm.di_local_variable +#spType1 = #llvm.di_subroutine_type +#sp1 = #llvm.di_subprogram< + compileUnit = #cu, scope = #file, name = "empty_types", + file = #file, subprogramFlags = "Definition", type = #spType1 +> + // CHECK-LABEL: define void @func_with_debug( // CHECK-SAME: i64 %[[ARG:.*]]) !dbg ![[FUNC_LOC:[0-9]+]] llvm.func @func_with_debug(%arg: i64) { @@ -93,10 +100,15 @@ llvm.func @func_with_debug(%arg: i64) { llvm.call @func_no_debug() : () -> () loc(fused[callsite("mysource.cc":5:6 at "mysource.cc":1:1), "mysource.cc":1:1]) // CHECK: add i64 %[[ARG]], %[[ARG]], !dbg ![[FUSEDWITH_LOC:[0-9]+]] - %sum = llvm.add %arg, %arg : i64 loc(fused<#callee>[callsite("foo.mlir":2:4 at fused<#sp>["foo.mlir":28:5])]) + %sum = llvm.add %arg, %arg : i64 loc(fused<#callee>[callsite("foo.mlir":2:4 at fused<#sp0>["foo.mlir":28:5])]) llvm.return -} loc(fused<#sp>["foo.mlir":1:1]) +} loc(fused<#sp0>["foo.mlir":1:1]) + +// CHECK: define void @empty_types() !dbg ![[EMPTY_TYPES_LOC:[0-9]+]] +llvm.func @empty_types() { + llvm.return +} loc(fused<#sp1>["foo.mlir":2:1]) // CHECK: ![[CU_LOC:.*]] = distinct !DICompileUnit(language: DW_LANG_C, file: ![[CU_FILE_LOC:.*]], producer: "MLIR", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug) // CHECK: ![[CU_FILE_LOC]] = !DIFile(filename: "foo.mlir", directory: "/test/") @@ -131,3 +143,7 @@ llvm.func @func_with_debug(%arg: i64) { // CHECK: ![[CALLEE_TYPE]] = !DISubroutineType(types: ![[CALLEE_ARGS:.*]]) // CHECK: ![[CALLEE_ARGS]] = !{![[ARG_TYPE:.*]], ![[ARG_TYPE:.*]]} // CHECK: ![[INLINE_LOC]] = !DILocation(line: 28, column: 5, + +// CHECK: ![[EMPTY_TYPES_LOC]] = distinct !DISubprogram(name: "empty_types", scope: ![[CU_FILE_LOC]], file: ![[CU_FILE_LOC]], type: ![[EMPTY_TYPES_TYPE:.*]], spFlags: DISPFlagDefinition +// CHECK: ![[EMPTY_TYPES_TYPE]] = !DISubroutineType(cc: DW_CC_normal, types: ![[EMPTY_TYPES_ARGS:.*]]) +// CHECK: ![[EMPTY_TYPES_ARGS]] = !{} -- 2.7.4