From 03389df735946dcc2f462df77126bd6f84aff880 Mon Sep 17 00:00:00 2001 From: Artem Gindinson Date: Fri, 30 Aug 2019 15:14:06 +0300 Subject: [PATCH] Fix Line debug info contradicting control flow semantics This fixes 'OpLine's being inserted between branch merge instructions and branch instructions. Although this has no functional effect, SPIR-V specification clearly states that Line instructions must precede branch merge instructions Signed-off-by: Artem Gindinson --- lib/SPIRV/LLVMToSPIRVDbgTran.cpp | 9 +++++++-- test/DebugInfo/DebugControlFlow.cl | 16 +++++++++++----- test/DebugInfo/DebugUnstructuredControlFlow.cl | 9 +++++---- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/lib/SPIRV/LLVMToSPIRVDbgTran.cpp b/lib/SPIRV/LLVMToSPIRVDbgTran.cpp index dad1b7109d..a8e8eed69b 100644 --- a/lib/SPIRV/LLVMToSPIRVDbgTran.cpp +++ b/lib/SPIRV/LLVMToSPIRVDbgTran.cpp @@ -205,10 +205,15 @@ void LLVMToSPIRVDbgTran::transLocationInfo() { LineNo = DL.getLine(); Col = DL.getCol(); V = SPIRVWriter->getTranslatedValue(&I); - // TODO: Resolve issue with OpLine being inserted between - // branch merge instruction and branch instruction. // According to the spec, OpLine for an OpBranch/OpBranchConditional // must precede the merge instruction and not the branch instruction + auto *VPrev = static_cast(V)->getPrevious(); + if (VPrev->getOpCode() == OpLoopMerge || + VPrev->getOpCode() == OpLoopControlINTEL) { + assert(V->getOpCode() == OpBranch || + V->getOpCode() == OpBranchConditional); + V = VPrev; + } BM->addLine(V, File ? File->getId() : getDebugInfoNone()->getId(), LineNo, Col); } diff --git a/test/DebugInfo/DebugControlFlow.cl b/test/DebugInfo/DebugControlFlow.cl index f50d3c298e..c353bcc55d 100644 --- a/test/DebugInfo/DebugControlFlow.cl +++ b/test/DebugInfo/DebugControlFlow.cl @@ -24,13 +24,19 @@ void sample() { } while (j++ < 10); } +// Check that all Line items are retained +// CHECK-SPIRV: Line [[File:[0-9]+]] 18 0 +// Control flow // CHECK-SPIRV: {{[0-9]+}} LoopMerge [[MergeBlock:[0-9]+]] [[ContinueTarget:[0-9]+]] 1 -// CHECK-SPIRV-NOT: ExtInst -// TODO: Check-not for Line (can only precede LoopMerge) -// CHECK-SPIRV: BranchConditional +// CHECK-SPIRV-NEXT: BranchConditional + +// Check that all Line items are retained +// CHECK-SPIRV: Line [[File]] 23 0 +// CHECK-SPIRV: Line [[File]] 24 0 +// Control flow // CHECK-SPIRV: {{[0-9]+}} LoopMerge [[MergeBlock:[0-9]+]] [[ContinueTarget:[0-9]+]] 1 -// CHECK-SPIRV-NOT: ExtInst -// CHECK-SPIRV: Branch +// CHECK-SPIRV-NEXT: Branch + // CHECK-LLVM: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !dbg !{{[0-9]+}}, !llvm.loop ![[MD:[0-9]+]] // CHECK-LLVM: ![[MD]] = distinct !{![[MD]], ![[MD_unroll:[0-9]+]]} // CHECK-LLVM: ![[MD_unroll]] = !{!"llvm.loop.unroll.enable"} diff --git a/test/DebugInfo/DebugUnstructuredControlFlow.cl b/test/DebugInfo/DebugUnstructuredControlFlow.cl index 7c34234e89..bb938ef02c 100644 --- a/test/DebugInfo/DebugUnstructuredControlFlow.cl +++ b/test/DebugInfo/DebugUnstructuredControlFlow.cl @@ -15,11 +15,12 @@ void sample() { for(;;); } +// Check that all Line items are retained +// CHECK-SPIRV: Line [[File:[0-9]+]] 15 0 +// Loop control // CHECK-SPIRV: 2 LoopControlINTEL 1 -// CHECK-SPIRV-NOT: ExtInst -// TODO: Check-not for Line (can only precede LoopControl) -// CHECK-SPIRV: {{[0-9]+}} Line {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} -// CHECK-SPIRV: Branch +// CHECK-SPIRV-NEXT: Branch + // CHECK-LLVM: br label %{{.*}}, !dbg !{{[0-9]+}}, !llvm.loop ![[MD:[0-9]+]] // CHECK-LLVM: ![[MD]] = distinct !{![[MD]], ![[MD_unroll:[0-9]+]]} // CHECK-LLVM: ![[MD_unroll]] = !{!"llvm.loop.unroll.enable"}