diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index 535cf8dfd2ced..87fa6b388f7a4 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -625,10 +625,10 @@ def LLVM_DINamespaceAttr : LLVM_Attr<"DINamespace", "di_namespace", def LLVM_DISubrangeAttr : LLVM_Attr<"DISubrange", "di_subrange", /*traits=*/[], "DINodeAttr"> { let parameters = (ins - OptionalParameter<"IntegerAttr">:$count, - OptionalParameter<"IntegerAttr">:$lowerBound, - OptionalParameter<"IntegerAttr">:$upperBound, - OptionalParameter<"IntegerAttr">:$stride + OptionalParameter<"::mlir::Attribute">:$count, + OptionalParameter<"::mlir::Attribute">:$lowerBound, + OptionalParameter<"::mlir::Attribute">:$upperBound, + OptionalParameter<"::mlir::Attribute">:$stride ); let assemblyFormat = "`<` struct(params) `>`"; } diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp index 6c011b3c756ff..a373c1fb5cdab 100644 --- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp +++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp @@ -217,21 +217,32 @@ DISubprogramAttr DebugImporter::translateImpl(llvm::DISubprogram *node) { } DISubrangeAttr DebugImporter::translateImpl(llvm::DISubrange *node) { - auto getIntegerAttrOrNull = [&](llvm::DISubrange::BoundType data) { - if (auto *constInt = llvm::dyn_cast_or_null(data)) + auto getAttrOrNull = [&](llvm::DISubrange::BoundType data) -> Attribute { + if (data.isNull()) + return nullptr; + if (auto *constInt = dyn_cast(data)) return IntegerAttr::get(IntegerType::get(context, 64), constInt->getSExtValue()); - return IntegerAttr(); + if (auto *expr = dyn_cast(data)) + return translateExpression(expr); + if (auto *var = dyn_cast(data)) { + if (auto *local = dyn_cast(var)) + return translate(local); + if (auto *global = dyn_cast(var)) + return translate(global); + return nullptr; + } + return nullptr; }; - IntegerAttr count = getIntegerAttrOrNull(node->getCount()); - IntegerAttr upperBound = getIntegerAttrOrNull(node->getUpperBound()); + Attribute count = getAttrOrNull(node->getCount()); + Attribute upperBound = getAttrOrNull(node->getUpperBound()); // Either count or the upper bound needs to be present. Otherwise, the // metadata is invalid. The conversion might fail due to unsupported DI nodes. if (!count && !upperBound) return {}; - return DISubrangeAttr::get( - context, count, getIntegerAttrOrNull(node->getLowerBound()), upperBound, - getIntegerAttrOrNull(node->getStride())); + return DISubrangeAttr::get(context, count, + getAttrOrNull(node->getLowerBound()), upperBound, + getAttrOrNull(node->getStride())); } DISubroutineTypeAttr diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp index dfb7d4952157d..aef7a06f96c34 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -314,11 +314,27 @@ llvm::DINamespace *DebugTranslation::translateImpl(DINamespaceAttr attr) { } llvm::DISubrange *DebugTranslation::translateImpl(DISubrangeAttr attr) { - auto getMetadataOrNull = [&](IntegerAttr attr) -> llvm::Metadata * { + auto getMetadataOrNull = [&](Attribute attr) -> llvm::Metadata * { if (!attr) return nullptr; - return llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned( - llvm::Type::getInt64Ty(llvmCtx), attr.getInt())); + + llvm::Metadata *metadata = + llvm::TypeSwitch(attr) + .Case([&](IntegerAttr intAttr) { + return llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned( + llvm::Type::getInt64Ty(llvmCtx), intAttr.getInt())); + }) + .Case([&](LLVM::DIExpressionAttr expr) { + return translateExpression(expr); + }) + .Case([&](LLVM::DILocalVariableAttr local) { + return translate(local); + }) + .Case<>([&](LLVM::DIGlobalVariableAttr global) { + return translate(global); + }) + .Default([&](Attribute attr) { return nullptr; }); + return metadata; }; return llvm::DISubrange::get(llvmCtx, getMetadataOrNull(attr.getCount()), getMetadataOrNull(attr.getLowerBound()), diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll index 72c828448d088..0c6a7368b7b88 100644 --- a/mlir/test/Target/LLVMIR/Import/debug-info.ll +++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll @@ -161,12 +161,17 @@ 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: #[[VAR:.+]] = #llvm.di_local_variable<{{.*}}name = "size"> +; CHECK-DAG: #[[GV:.+]] = #llvm.di_global_variable<{{.*}}name = "gv"{{.*}}> ; 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> -; CHECK-DAG: #[[COMP5:.+]] = #llvm.di_composite_type<{{.*}}, flags = Vector> -; CHECK-DAG: #llvm.di_subroutine_type +; CHECK-DAG: #[[COMP5:.+]] = #llvm.di_composite_type<{{.*}}, name = "var_elements"{{.*}}elements = #llvm.di_subrange> +; CHECK-DAG: #[[COMP6:.+]] = #llvm.di_composite_type<{{.*}}, name = "expr_elements"{{.*}}elements = #llvm.di_subrange>> +; CHECK-DAG: #llvm.di_subroutine_type + +@gv = external global i64 define void @composite_type() !dbg !3 { ret void @@ -179,7 +184,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 = !{!7, !8, !9, !10, !18} +!5 = !{!7, !8, !9, !10, !18, !22} !6 = !DIBasicType(name: "int") !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) @@ -189,12 +194,16 @@ define void @composite_type() !dbg !3 { !12 = !DISubrange(lowerBound: 0, upperBound: 4, stride: 1) !13 = !{!11} !14 = !{!12} - -; Verifies that unsupported subrange nodes are skipped. -!15 = !DISubrange(count: !16) +!15 = !DISubrange(count: !16, stride: !23) !16 = !DILocalVariable(scope: !3, name: "size") !17 = !{!15} -!18 = !DICompositeType(tag: DW_TAG_array_type, name: "unsupported_elements", flags: DIFlagVector, elements: !17, baseType: !6) +!18 = !DICompositeType(tag: DW_TAG_array_type, name: "var_elements", flags: DIFlagVector, elements: !17, baseType: !6) +!19 = !DISubrange(count: !20) +!20 = !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 16, DW_OP_deref) +!21 = !{!19} +!22 = !DICompositeType(tag: DW_TAG_array_type, name: "expr_elements", flags: DIFlagVector, elements: !21, baseType: !6) +!23 = !DIGlobalVariable(name: "gv", scope: !1, file: !2, line: 3, type: !6, isLocal: false, isDefinition: false) + ; // ----- diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir index e5c233bc5e9bb..724f45f0d2a87 100644 --- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir @@ -519,3 +519,48 @@ llvm.func @fn_with_composite() { // CHECK-SAME: associated: !DIExpression(DW_OP_lit0, DW_OP_eq) // CHECK-SAME: allocated: !DIExpression(DW_OP_lit0, DW_OP_ne) // CHECK-SAME: rank: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 16, DW_OP_deref) + +// ----- + +// Test that Subrange works with expression and variables. + +#bt = #llvm.di_basic_type +#file = #llvm.di_file<"debug-info.ll" in "/"> +#cu = #llvm.di_compile_unit, + sourceLanguage = DW_LANG_Fortran95, file = #file, isOptimized = false, + emissionKind = Full> +#comp_ty1 = #llvm.di_composite_type>> +#srty = #llvm.di_subroutine_type +#sp = #llvm.di_subprogram +#lvar = #llvm.di_local_variable +#gv = #llvm.di_global_variable +#gve = #llvm.di_global_variable_expression> +#comp_ty2 = #llvm.di_composite_type> +#lvar2 = #llvm.di_local_variable +#loc1 = loc("test.f90": 1:1) +#loc2 = loc(fused<#sp>[#loc1]) + +llvm.mlir.global external @gv() {dbg_expr = #gve} : i64 + +llvm.func @subranges(%arg: !llvm.ptr) { + llvm.intr.dbg.declare #lvar2 = %arg : !llvm.ptr + llvm.return +} loc(#loc2) + +// CHECK-LABEL: define void @subranges +// CHECK: ![[GV:[0-9]+]] = {{.*}}!DIGlobalVariable(name: "gv"{{.*}}) +// CHECK: !DICompositeType(tag: DW_TAG_array_type, name: "expr_elements"{{.*}}elements: ![[ELEMENTS1:[0-9]+]]) +// CHECK: ![[ELEMENTS1]] = !{![[ELEMENT1:[0-9]+]]} +// CHECK: ![[ELEMENT1]] = !DISubrange(count: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 16, DW_OP_deref)) + +// CHECK: !DICompositeType(tag: DW_TAG_array_type, name: "var_elements"{{.*}}elements: ![[ELEMENTS2:[0-9]+]]) +// CHECK: ![[ELEMENTS2]] = !{![[ELEMENT2:[0-9]+]]} +// CHECK: ![[ELEMENT2]] = !DISubrange(count: ![[LV:[0-9]+]], stride: ![[GV:[0-9]+]]) +// CHECK: ![[LV]] = !DILocalVariable(name: "size"{{.*}})