diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -261,11 +261,11 @@ >; //===----------------------------------------------------------------------===// -// DIVoidResultTypeAttr +// DINullTypeAttr //===----------------------------------------------------------------------===// -def LLVM_DIVoidResultTypeAttr : LLVM_Attr<"DIVoidResultType", "di_void_result_type", - /*traits=*/[], "DITypeAttr"> { +def LLVM_DINullTypeAttr : LLVM_Attr<"DINullType", "di_null_type", + /*traits=*/[], "DITypeAttr"> { let parameters = (ins); } @@ -442,7 +442,7 @@ def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram", /*traits=*/[], "DIScopeAttr"> { let parameters = (ins - "DICompileUnitAttr":$compileUnit, + OptionalParameter<"DICompileUnitAttr">:$compileUnit, "DIScopeAttr":$scope, "StringAttr":$name, OptionalParameter<"StringAttr">:$linkageName, @@ -500,7 +500,6 @@ }]> ]; let assemblyFormat = "`<` struct(params) `>`"; - let genVerifyDecl = 1; } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp @@ -42,7 +42,7 @@ //===----------------------------------------------------------------------===// bool DINodeAttr::classof(Attribute 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(); -} - //===----------------------------------------------------------------------===// // MemoryEffectsAttr //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -2759,7 +2759,7 @@ AliasResult getAlias(Attribute attr, raw_ostream &os) const override { return TypeSwitch(attr) - .Case 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)); + // A nullptr entry may appear at the beginning or the end of the + // subroutine types list modeling either a void result type or the type of + // a variadic argument. Translate the nullptr to an explicit + // DINullTypeAttr since the attribute list cannot contain a nullptr entry. + types.push_back(DINullTypeAttr::get(context)); continue; } types.push_back(translate(type)); diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h --- a/mlir/lib/Target/LLVMIR/DebugTranslation.h +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h @@ -61,7 +61,7 @@ llvm::DIFile *translateFile(StringRef fileName); /// Translate the given attribute to the corresponding llvm debug metadata. - llvm::DIType *translateImpl(DIVoidResultTypeAttr attr); + llvm::DIType *translateImpl(DINullTypeAttr attr); llvm::DIBasicType *translateImpl(DIBasicTypeAttr attr); llvm::DICompileUnit *translateImpl(DICompileUnitAttr attr); llvm::DICompositeType *translateImpl(DICompositeTypeAttr attr); diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -88,10 +88,11 @@ // 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 +llvm::DIType *DebugTranslation::translateImpl(DINullTypeAttr attr) { + // A DINullTypeAttr at the beginning of the subroutine types list models + // a void result type. If it is at the end, it models a variadic function. + // Translate the explicit DINullTypeAttr to a nullptr since LLVM IR metadata + // does not have an explicit void result type nor a variadic type // representation. return nullptr; } @@ -234,7 +235,7 @@ llvm::DINode *node = TypeSwitch(attr) - .Case( diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir --- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir +++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir @@ -9,8 +9,8 @@ isOptimized = true, emissionKind = Full > -// CHECK-DAG: #[[VOID:.*]] = #llvm.di_void_result_type -#void = #llvm.di_void_result_type +// CHECK-DAG: #[[NULL:.*]] = #llvm.di_null_type +#null = #llvm.di_null_type // CHECK-DAG: #[[INT0:.*]] = #llvm.di_basic_type #int0 = #llvm.di_basic_type< @@ -56,9 +56,9 @@ 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, types = #void, #int0, #ptr0, #ptr1, #comp0, #comp1, #comp2 + callingConvention = DW_CC_normal, types = #null, #int0, #ptr0, #ptr1, #comp0, #comp1, #comp2 > // CHECK-DAG: #[[SPTYPE1:.*]] = #llvm.di_subroutine_type diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir --- a/mlir/test/Dialect/LLVMIR/invalid.mlir +++ b/mlir/test/Dialect/LLVMIR/invalid.mlir @@ -1300,12 +1300,6 @@ // ----- -#void = #llvm.di_void_result_type -// expected-error@below {{expected subroutine to have non-void argument types}} -#void_argument_type = #llvm.di_subroutine_type - -// ----- - func.func @invalid_bitcast_ptr_to_i64(%arg : !llvm.ptr) { // expected-error@+1 {{can only cast pointers from and to pointers}} %1 = llvm.bitcast %arg : !llvm.ptr to i64 diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll --- a/mlir/test/Target/LLVMIR/Import/debug-info.ll +++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll @@ -112,10 +112,10 @@ ; // ----- -; CHECK-DAG: #[[VOID:.+]] = #llvm.di_void_result_type +; CHECK-DAG: #[[NULL:.+]] = #llvm.di_null_type ; CHECK-DAG: #[[INT1:.+]] = #llvm.di_basic_type ; CHECK-DAG: #[[INT2:.+]] = #llvm.di_basic_type -; CHECK-DAG: #llvm.di_subroutine_type +; CHECK-DAG: #llvm.di_subroutine_type define void @basic_type() !dbg !3 { ret void @@ -328,3 +328,19 @@ !7 = !DILocalVariable(scope: !8, name: "class_field", file: !2, type: !5); !8 = distinct !DISubprogram(name: "class_field", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1) !9 = !DILocation(line: 1, column: 2, scope: !8) + +; // ----- + +; CHECK-DAG: #[[NULL:.+]] = #llvm.di_null_type +; CHECK-DAG: #llvm.di_subroutine_type + +declare !dbg !3 void @variadic_func() + +!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: "debug-info.ll", directory: "/") +!3 = !DISubprogram(name: "variadic_func", scope: !2, file: !2, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, type: !4) +!4 = !DISubroutineType(types: !5) +!5 = !{null, null} diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir --- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir @@ -48,8 +48,8 @@ baseType = #si64, flags = Vector, elements = #llvm.di_subrange > -#void = #llvm.di_void_result_type -#spType0 = #llvm.di_subroutine_type +#null = #llvm.di_null_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 = #spType0