diff --git a/lib/SPIRV/LLVMToSPIRVDbgTran.cpp b/lib/SPIRV/LLVMToSPIRVDbgTran.cpp index 3301bd4479..1d62dc030b 100644 --- a/lib/SPIRV/LLVMToSPIRVDbgTran.cpp +++ b/lib/SPIRV/LLVMToSPIRVDbgTran.cpp @@ -481,6 +481,14 @@ SPIRVWord adjustAccessFlags(DIScope *Scope, SPIRVWord Flags) { return Flags; } +// Fortran dynamic arrays can have following 'dataLocation', 'associated' +// 'allocated' and 'rank' debug metadata. Such arrays are being mapped on +// DebugTypeArrayDynamic from NonSemantic.Kernel.100 debug spec +inline bool isFortranArrayDynamic(const DICompositeType *AT) { + return (AT->getRawDataLocation() || AT->getRawAssociated() || + AT->getRawAllocated() || AT->getRawRank()); +} + /// The following methods (till the end of the file) implement translation of /// debug instrtuctions described in the spec. @@ -561,8 +569,11 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgQualifiedType(const DIDerivedType *QT) { } SPIRVEntry *LLVMToSPIRVDbgTran::transDbgArrayType(const DICompositeType *AT) { - if (BM->getDebugInfoEIS() == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100) + if (BM->getDebugInfoEIS() == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100) { + if (isFortranArrayDynamic(AT)) + return transDbgArrayTypeDynamic(AT); return transDbgArrayTypeNonSemantic(AT); + } return transDbgArrayTypeOpenCL(AT); } @@ -571,8 +582,7 @@ SPIRVEntry * LLVMToSPIRVDbgTran::transDbgArrayTypeOpenCL(const DICompositeType *AT) { using namespace SPIRVDebug::Operand::TypeArray; SPIRVWordVec Ops(MinOperandCount); - SPIRVEntry *Base = transDbgEntry(AT->getBaseType()); - Ops[BaseTypeIdx] = Base->getId(); + Ops[BaseTypeIdx] = transDbgEntry(AT->getBaseType())->getId(); DINodeArray AR(AT->getElements()); // For N-dimensianal arrays AR.getNumElements() == N @@ -615,8 +625,7 @@ SPIRVEntry * LLVMToSPIRVDbgTran::transDbgArrayTypeNonSemantic(const DICompositeType *AT) { using namespace SPIRVDebug::Operand::TypeArray; SPIRVWordVec Ops(MinOperandCount); - SPIRVEntry *Base = transDbgEntry(AT->getBaseType()); - Ops[BaseTypeIdx] = Base->getId(); + Ops[BaseTypeIdx] = transDbgEntry(AT->getBaseType())->getId(); DINodeArray AR(AT->getElements()); // For N-dimensianal arrays AR.getNumElements() == N @@ -635,6 +644,43 @@ LLVMToSPIRVDbgTran::transDbgArrayTypeNonSemantic(const DICompositeType *AT) { return BM->addDebugInfo(SPIRVDebug::TypeArray, getVoidTy(), Ops); } +// The function is used to translate Fortran's dynamic arrays +SPIRVEntry * +LLVMToSPIRVDbgTran::transDbgArrayTypeDynamic(const DICompositeType *AT) { + using namespace SPIRVDebug::Operand::TypeArrayDynamic; + SPIRVWordVec Ops(MinOperandCount); + Ops[BaseTypeIdx] = transDbgEntry(AT->getBaseType())->getId(); + + // DataLocation, Associated, Allocated and Rank can be either DIExpression + // metadata or DIVariable + auto TransOperand = [&](llvm::Metadata *DIMD) -> SPIRVWord { + if (auto *DIExpr = dyn_cast_or_null(DIMD)) + return transDbgExpression(DIExpr)->getId(); + if (auto *DIVar = dyn_cast_or_null(DIMD)) { + if (const DILocalVariable *LV = dyn_cast(DIVar)) + return transDbgLocalVariable(LV)->getId(); + if (const DIGlobalVariable *GV = dyn_cast(DIVar)) + return transDbgGlobalVariable(GV)->getId(); + } + return getDebugInfoNoneId(); + }; + + Ops[DataLocationIdx] = TransOperand(AT->getRawDataLocation()); + Ops[AssociatedIdx] = TransOperand(AT->getRawAssociated()); + Ops[AllocatedIdx] = TransOperand(AT->getRawAllocated()); + Ops[RankIdx] = TransOperand(AT->getRawRank()); + + DINodeArray AR(AT->getElements()); + // For N-dimensianal arrays AR.getNumElements() == N + const unsigned N = AR.size(); + Ops.resize(SubrangesIdx + N); + for (unsigned I = 0; I < N; ++I) { + DISubrange *SR = cast(AR[I]); + Ops[SubrangesIdx + I] = transDbgEntry(SR)->getId(); + } + return BM->addDebugInfo(SPIRVDebug::TypeArrayDynamic, getVoidTy(), Ops); +} + SPIRVEntry *LLVMToSPIRVDbgTran::transDbgSubrangeType(const DISubrange *ST) { using namespace SPIRVDebug::Operand::TypeSubrange; SPIRVWordVec Ops(OperandCount); diff --git a/lib/SPIRV/LLVMToSPIRVDbgTran.h b/lib/SPIRV/LLVMToSPIRVDbgTran.h index 4a824bb3e6..5024ce2e61 100644 --- a/lib/SPIRV/LLVMToSPIRVDbgTran.h +++ b/lib/SPIRV/LLVMToSPIRVDbgTran.h @@ -107,6 +107,7 @@ class LLVMToSPIRVDbgTran { SPIRVEntry *transDbgArrayType(const DICompositeType *AT); SPIRVEntry *transDbgArrayTypeOpenCL(const DICompositeType *AT); SPIRVEntry *transDbgArrayTypeNonSemantic(const DICompositeType *AT); + SPIRVEntry *transDbgArrayTypeDynamic(const DICompositeType *AT); SPIRVEntry *transDbgSubrangeType(const DISubrange *ST); SPIRVEntry *transDbgTypeDef(const DIDerivedType *D); SPIRVEntry *transDbgSubroutineType(const DISubroutineType *FT); diff --git a/lib/SPIRV/SPIRVToLLVMDbgTran.cpp b/lib/SPIRV/SPIRVToLLVMDbgTran.cpp index 49a5f5bb28..6c280df4bb 100644 --- a/lib/SPIRV/SPIRVToLLVMDbgTran.cpp +++ b/lib/SPIRV/SPIRVToLLVMDbgTran.cpp @@ -273,7 +273,7 @@ SPIRVToLLVMDbgTran::transTypeArrayNonSemantic(const SPIRVExtInst *DebugInst) { for (size_t I = SubrangesIdx; I < Ops.size(); ++I) { auto *SR = transDebugInst(BM->get(Ops[I])); if (auto *Count = SR->getCount().get()) - TotalCount *= Count->getZExtValue() > 0 ? Count->getZExtValue() : 0; + TotalCount *= Count->getSExtValue() > 0 ? Count->getSExtValue() : 0; Subscripts.push_back(SR); } } @@ -282,6 +282,47 @@ SPIRVToLLVMDbgTran::transTypeArrayNonSemantic(const SPIRVExtInst *DebugInst) { return Builder.createArrayType(Size, 0 /*align*/, BaseTy, SubscriptArray); } +DICompositeType * +SPIRVToLLVMDbgTran::transTypeArrayDynamic(const SPIRVExtInst *DebugInst) { + using namespace SPIRVDebug::Operand::TypeArrayDynamic; + const SPIRVWordVec &Ops = DebugInst->getArguments(); + assert(Ops.size() >= MinOperandCount && "Invalid number of operands"); + DIType *BaseTy = + transDebugInst(BM->get(Ops[BaseTypeIdx])); + size_t TotalCount = 1; + SmallVector Subscripts; + for (size_t I = SubrangesIdx; I < Ops.size(); ++I) { + auto *SR = transDebugInst(BM->get(Ops[I])); + if (auto *Count = SR->getCount().get()) + TotalCount *= Count->getSExtValue() > 0 ? Count->getSExtValue() : 0; + Subscripts.push_back(SR); + } + DINodeArray SubscriptArray = Builder.getOrCreateArray(Subscripts); + size_t Size = getDerivedSizeInBits(BaseTy) * TotalCount; + + auto TransOperand = [&](SPIRVWord Idx) -> PointerUnion { + if (!getDbgInst(Ops[Idx])) { + if (const auto *GV = getDbgInst(Ops[Idx])) + return transDebugInst(GV); + if (const auto *LV = getDbgInst(Ops[Idx])) + return transDebugInst(LV); + if (const auto *DIExpr = getDbgInst(Ops[Idx])) + return transDebugInst(DIExpr); + } + return nullptr; + }; + PointerUnion DataLocation = + TransOperand(DataLocationIdx); + PointerUnion Associated = + TransOperand(AssociatedIdx); + PointerUnion Allocated = + TransOperand(AllocatedIdx); + PointerUnion Rank = TransOperand(RankIdx); + return Builder.createArrayType(Size, 0 /*align*/, BaseTy, SubscriptArray, + DataLocation, Associated, Allocated, Rank); +} + DICompositeType * SPIRVToLLVMDbgTran::transTypeVector(const SPIRVExtInst *DebugInst) { using namespace SPIRVDebug::Operand::TypeVector; @@ -1037,6 +1078,9 @@ MDNode *SPIRVToLLVMDbgTran::transDebugInstImpl(const SPIRVExtInst *DebugInst) { case SPIRVDebug::Expression: return transExpression(DebugInst); + case SPIRVDebug::TypeArrayDynamic: + return transTypeArrayDynamic(DebugInst); + default: llvm_unreachable("Not implemented SPIR-V debug instruction!"); } diff --git a/lib/SPIRV/SPIRVToLLVMDbgTran.h b/lib/SPIRV/SPIRVToLLVMDbgTran.h index 16edb78e70..000cda6c49 100644 --- a/lib/SPIRV/SPIRVToLLVMDbgTran.h +++ b/lib/SPIRV/SPIRVToLLVMDbgTran.h @@ -114,6 +114,7 @@ class SPIRVToLLVMDbgTran { DICompositeType *transTypeArray(const SPIRVExtInst *DebugInst); DICompositeType *transTypeArrayOpenCL(const SPIRVExtInst *DebugInst); DICompositeType *transTypeArrayNonSemantic(const SPIRVExtInst *DebugInst); + DICompositeType *transTypeArrayDynamic(const SPIRVExtInst *DebugInst); DICompositeType *transTypeVector(const SPIRVExtInst *DebugInst); diff --git a/lib/SPIRV/libSPIRV/SPIRV.debug.h b/lib/SPIRV/libSPIRV/SPIRV.debug.h index 0730c6f20d..baacef5e2c 100644 --- a/lib/SPIRV/libSPIRV/SPIRV.debug.h +++ b/lib/SPIRV/libSPIRV/SPIRV.debug.h @@ -52,7 +52,8 @@ enum Instruction { Source = 35, ModuleINTEL = 36, InstCount = 37, - TypeSubrange = 110 + TypeSubrange = 110, + TypeArrayDynamic = 202 }; enum Flag { @@ -330,6 +331,18 @@ enum { }; } +namespace TypeArrayDynamic { +enum { + BaseTypeIdx = 0, + DataLocationIdx = 1, + AssociatedIdx = 2, + AllocatedIdx = 3, + RankIdx = 4, + SubrangesIdx = 5, + MinOperandCount = 6 +}; +} + namespace TypeVector = TypeArray; namespace TypeSubrange { diff --git a/lib/SPIRV/libSPIRV/SPIRVExtInst.h b/lib/SPIRV/libSPIRV/SPIRVExtInst.h index 245552900c..23576fc6a1 100644 --- a/lib/SPIRV/libSPIRV/SPIRVExtInst.h +++ b/lib/SPIRV/libSPIRV/SPIRVExtInst.h @@ -226,6 +226,7 @@ template <> inline void SPIRVMap::init() { add(SPIRVDebug::TypeBasic, "DebugTypeBasic"); add(SPIRVDebug::TypePointer, "DebugTypePointer"); add(SPIRVDebug::TypeArray, "DebugTypeArray"); + add(SPIRVDebug::TypeArrayDynamic, "DebugTypeArrayDynamic"); add(SPIRVDebug::TypeVector, "DebugTypeVector"); add(SPIRVDebug::TypeQualifier, "DebugTypeQualifier"); add(SPIRVDebug::TypeFunction, "DebugTypeFunction"); diff --git a/test/DebugInfo/NonSemanticKernel100/FortranArray.ll b/test/DebugInfo/NonSemanticKernel100/FortranArray.ll index b9d3744709..6b5d88a3db 100644 --- a/test/DebugInfo/NonSemanticKernel100/FortranArray.ll +++ b/test/DebugInfo/NonSemanticKernel100/FortranArray.ll @@ -6,7 +6,10 @@ ; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM ; CHECK-LLVM: !DICompileUnit(language: DW_LANG_Fortran95 -; CHECK-LLVM: !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref, DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref, DW_OP_plus, DW_OP_constu, 1, DW_OP_minus), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref)) +; CHECK-LLVM: !DICompositeType(tag: DW_TAG_array_type, baseType: ![[#BaseT:]], size: 32, elements: ![[#Elements:]], dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref, DW_OP_constu, 0, DW_OP_or)) +; CHECK-LLVM: ![[#BaseT:]] = !DIBasicType(name: "INTEGER*4", size: 32, encoding: DW_ATE_signed) +; CHECK-LLVM: ![[#Elements]] = !{![[#SubRange:]]} +; CHECK-LLVM: ![[#SubRange]] = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref, DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref, DW_OP_plus, DW_OP_constu, 1, DW_OP_minus), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref)) source_filename = "llvm-link" target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" diff --git a/test/DebugInfo/NonSemanticKernel100/FortranDynamicArrayExpr.ll b/test/DebugInfo/NonSemanticKernel100/FortranDynamicArrayExpr.ll new file mode 100644 index 0000000000..0aa4c1f7f1 --- /dev/null +++ b/test/DebugInfo/NonSemanticKernel100/FortranDynamicArrayExpr.ll @@ -0,0 +1,81 @@ +;; The test checks, that Fortran dynamic arrays are being correctly represented +;; by SPIR-V debug information +;; Unlike 'static' arrays dynamic can have following parameters of +;; DICompositeType metadata with DW_TAG_array_type tag: +;; Data Location, Associated, Allocated and Rank which can be represented +;; by either DIExpression or DIVariable (both local and global). +;; This test if for expression representation. +;; FortranDynamicArrayVar.ll is for variable representation. + +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -spirv-text --spirv-debug-info-version=nonsemantic-kernel-100 -o - | FileCheck %s --check-prefix=CHECK-SPIRV +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-debug-info-version=nonsemantic-kernel-100 +; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o %t.rev.bc +; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM + +; CHECK-SPIRV-DAG: ExtInstImport [[#Import:]] "NonSemantic.Kernel.DebugInfo.100" +; CHECK-SPIRV-DAG: String [[#BasicTName:]] "INTEGER*4" +; CHECK-SPIRV-DAG: TypeInt [[#Int32T:]] 32 0 +; CHECK-SPIRV-DAG: Constant [[#Int32T]] [[#IntConst:]] 32 +; CHECK-SPIRV-DAG: TypeVoid [[#VoidT:]] +; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgInfoNone:]] [[#Import]] DebugInfoNone +; CHECK-SPIRV: ExtInst [[#VoidT]] [[#ArrayBasicT:]] [[#Import]] DebugTypeBasic [[#BasicTName]] [[#IntConst]] 4 +; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgExprLocation:]] [[#Import]] DebugExpression [[#]] [[#]] {{$}} +; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgExprAssociated:]] [[#Import]] DebugExpression [[#]] [[#]] [[#]] [[#]] {{$}} +; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgExprLowerBound:]] [[#Import]] DebugExpression [[#]] [[#]] [[#]] {{$}} +; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgExprUpperBound:]] [[#Import]] DebugExpression [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] {{$}} +; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgExprCount:]] [[#Import]] DebugExpression [[#]] [[#]] [[#]] {{$}} +; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgSubRangeId:]] [[#Import]] DebugTypeSubrange [[#DbgInfoNone]] [[#DbgExprLowerBound]] [[#DbgExprUpperBound]] [[#DbgExprCount]] +; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgArrayId:]] [[#Import]] DebugTypeArrayDynamic [[#ArrayBasicT]] [[#DbgExprLocation]] [[#DbgExprAssociated]] [[#DbgInfoNone]] [[#DbgInfoNone]] [[#DbgSubRangeId]] + +; CHECK-LLVM: %[[#Array:]] = alloca +; CHECK-LLVM: call void @llvm.dbg.value(metadata ptr %[[#Array]], metadata ![[#DbgLVar:]] +; CHECK-LLVM: ![[#DbgLVar]] = !DILocalVariable(name: "pint", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#DbgLVarT:]]) +; CHECK-LLVM: ![[#DbgLVarT]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[#DbgArrayT:]], size: 64) +; CHECK-LLVM: ![[#DbgArrayT]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[#DbgArrayBaseT:]], size: 32, elements: ![[#Elements:]], dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref, DW_OP_constu, 0, DW_OP_or)) +; CHECK-LLVM: ![[#DbgArrayBaseT]] = !DIBasicType(name: "INTEGER*4", size: 32, encoding: DW_ATE_signed) +; CHECK-LLVM: ![[#Elements]] = !{![[#SubRange:]]} +; CHECK-LLVM: ![[#SubRange]] = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref, DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref, DW_OP_plus, DW_OP_constu, 1, DW_OP_minus), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref)) + + +; ModuleID = 'reproducer.ll' +source_filename = "test.f90" +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir64" + +%qnca = type { i32 addrspace(4)*, i64, i64, i64, i64, i64, [1 x { i64, i64, i64 }] } + +; Function Attrs: noinline nounwind optnone +define weak dso_local spir_kernel void @TEST() #0 !dbg !5 { +newFuncRoot: + %0 = alloca %qnca, align 8 + call void @llvm.dbg.value(metadata %qnca* %0, metadata !8, metadata !DIExpression()), !dbg !14 + ret void +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { noinline nounwind optnone } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } + +!llvm.module.flags = !{!0, !1} +!llvm.dbg.cu = !{!2} +!spirv.Source = !{!4} + +!0 = !{i32 2, !"Debug Info Version", i32 3} +!1 = !{i32 2, !"Dwarf Version", i32 4} +!2 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "fortran", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +!3 = !DIFile(filename: "test.f90", directory: "/path/to") +!4 = !{i32 4, i32 200000} +!5 = distinct !DISubprogram(name: "test", linkageName: "MAIN__", scope: !3, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2) +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = !DILocalVariable(name: "pint", scope: !5, file: !3, line: 3, type: !9) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, elements: !12, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref, DW_OP_constu, 0, DW_OP_or)) +!11 = !DIBasicType(name: "INTEGER*4", size: 32, encoding: DW_ATE_signed) +!12 = !{!13} +!13 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref, DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref, DW_OP_plus, DW_OP_constu, 1, DW_OP_minus), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref)) +!14 = !DILocation(line: 1, scope: !5) + diff --git a/test/DebugInfo/NonSemanticKernel100/FortranDynamicArrayVar.ll b/test/DebugInfo/NonSemanticKernel100/FortranDynamicArrayVar.ll new file mode 100644 index 0000000000..29f01ffd6b --- /dev/null +++ b/test/DebugInfo/NonSemanticKernel100/FortranDynamicArrayVar.ll @@ -0,0 +1,74 @@ +;; DebugInfo/dwarfdump-dataLocationVar.ll from llvm.org is used as base for this test +;; The test checks, that Fortran dynamic arrays are being correctly represented +;; by SPIR-V debug information +;; Unlike 'static' arrays dynamic can have following parameters of +;; DICompositeType metadata with DW_TAG_array_type tag: +;; Data Location, Associated, Allocated and Rank which can be represented +;; by either DIExpression or DIVariable (both local and global). +;; This test if for variable representation. +;; FortranDynamicArrayVar.ll is for expression representation. + +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -spirv-text --spirv-debug-info-version=nonsemantic-kernel-100 -o - | FileCheck %s --check-prefix=CHECK-SPIRV +; RUN: llvm-spirv %t.bc -o %t.spv --spirv-debug-info-version=nonsemantic-kernel-100 +; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o %t.rev.bc +; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM + +;; Major SPIR-V checks are done in FortranDynamicArrayExpr.ll +; CHECK-SPIRV: ExtInst [[#]] [[#DbgLVarId:]] [[#]] DebugLocalVariable [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] {{$}} +; CHECK-SPIRV: ExtInst [[#]] [[#]] [[#]] DebugTypeArrayDynamic [[#]] [[#DbgLVarId]] [[#]] [[#]] [[#]] [[#]] + +; CHECK-LLVM: %[[#Ptr:]] = alloca ptr +; CHECK-LLVM: %[[#Array:]] = alloca [16 x i64] +; CHECK-LLVM: call void @llvm.dbg.declare(metadata ptr %[[#Array]], metadata ![[#DbgLVarArray:]] +; CHECK-LLVM: call void @llvm.dbg.declare(metadata ptr %[[#Ptr]], metadata ![[#DbgLVarPtr:]] + +; CHECK-LLVM: ![[#DbgLVarPtr:]] = !DILocalVariable(scope: ![[#]], file: ![[#]], type: ![[#DbgPtrT:]], flags: DIFlagArtificial) +; CHECK-LLVM: ![[#DbgPtrT:]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[#DbgBasicT:]], size: 64) +; CHECK-LLVM: ![[#DbgBasicT]] = !DIBasicType(name: "integer", size: 32, encoding: DW_ATE_signed) +; CHECK-LLVM: ![[#DbgLVarArray]] = !DILocalVariable(name: "arr", scope: ![[#]], file: ![[#]], type: ![[#DbgArrayT:]]) +; CHECK-LLVM: ![[#DbgArrayT]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[#DbgBasicT]], size: 608, elements: ![[#Elements:]], dataLocation: ![[#DbgLVarPtr]]) +; CHECK-LLVM: ![[#Elements]] = !{![[#SubRange:]]} +; CHECK-LLVM: ![[#SubRange]] = !DISubrange(count: 19, lowerBound: 2) + +; ModuleID = 'fortsubrange.ll' +source_filename = "fortsubrange.ll" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "spir64-unknown-unknown" + +define spir_func void @foo() !dbg !5 { +L.entry: + %0 = alloca ptr, align 8 + %1 = alloca [16 x i64], align 8 + call void @llvm.dbg.declare(metadata ptr %1, metadata !8, metadata !DIExpression()), !dbg !16 + call void @llvm.dbg.declare(metadata ptr %0, metadata !14, metadata !DIExpression()), !dbg !16 + ret void, !dbg !17 +} + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.module.flags = !{!0, !1} +!llvm.dbg.cu = !{!2} + +!0 = !{i32 2, !"Dwarf Version", i32 4} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4) +!3 = !DIFile(filename: "fortsubrange.f90", directory: "/dir") +!4 = !{} +!5 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2) +!6 = !DISubroutineType(cc: DW_CC_program, types: !7) +!7 = !{null} +!8 = !DILocalVariable(name: "arr", scope: !9, file: !3, type: !10) +!9 = !DILexicalBlock(scope: !5, file: !3, line: 1, column: 1) +!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, size: 32, align: 32, elements: !12, dataLocation: !14) +!11 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!12 = !{!13} +!13 = !DISubrange(count: 19, lowerBound: 2) +!14 = distinct !DILocalVariable(scope: !9, file: !3, type: !15, flags: DIFlagArtificial) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 32, align: 32) +!16 = !DILocation(line: 0, scope: !9) +!17 = !DILocation(line: 6, column: 1, scope: !9)