This was landed but reverted in 5b9c2b1bea due to asan picking up a memory
leak. This is fixed in the change to InstrRefBasedImpl.cpp. Original
commit message follows:
[LiveDebugValues][NFC] Add instr-ref tests, adapt old tests
This patch adds a few tests in DebugInfo/MIR/InstrRef/ of interesting
behaviour that the instruction referencing implementation of
LiveDebugValues has. Mostly, these tests exist to ensure that if you
give the "-experimental-debug-variable-locations" command line switch,
the right implementation runs; and to ensure it behaves the same way as
the VarLoc LiveDebugValues implementation.
I've also touched roughly 30 other tests, purely to make the tests less
rigid about what output to accept. DBG_VALUE instructions are usually
printed with a trailing !debug-location indicating its scope:
!debug-location !1234
However InstrRefBasedLDV produces new DebugLoc instances on the fly,
meaning there sometimes isn't a numbered node when they're printed,
making the output:
!debug-location !DILocation(line: 0, blah blah)
Which causes a ton of these tests to fail. This patch removes checks for
that final part of each DBG_VALUE instruction. None of them appear to
be actually checking the scope is correct, just that it's present, so
I don't believe there's any loss in coverage here.
Differential Revision: https://reviews.llvm.org/D83054
300 lines
13 KiB
YAML
300 lines
13 KiB
YAML
# RUN: llc -run-pass=livedebugvalues -march=x86-64 -o - %s | FileCheck %s
|
|
|
|
# Test the extension of debug ranges from 3 predecessors.
|
|
# Generated from the source file LiveDebugValues-3preds.c:
|
|
# #include <stdio.h>
|
|
# int add(int x, int y, int z, int a) {
|
|
# int i;
|
|
# for (i = 0; i < x * y; i++) {
|
|
# if (i < x) {
|
|
# a = a * x;
|
|
# break;
|
|
# }
|
|
# if (i < y) {
|
|
# a = a * y;
|
|
# break;
|
|
# }
|
|
# if (i < z) {
|
|
# a = a * z;
|
|
# break;
|
|
# }
|
|
# }
|
|
# return a;
|
|
# }
|
|
# with clang -g -O1 -c -emit-llvm LiveDebugValues-3preds.c -S -o live-debug-values-3preds.ll
|
|
# then llc -stop-after stackmap-liveness live-debug-values-3preds.ll -o /dev/null > live-debug-values-3preds.mir
|
|
|
|
# CHECK: ![[X_VAR:[0-9]+]] = !DILocalVariable(name: "x", {{.*}})
|
|
# CHECK: ![[Y_VAR:[0-9]+]] = !DILocalVariable(name: "y", {{.*}})
|
|
# CHECK: ![[Z_VAR:[0-9]+]] = !DILocalVariable(name: "z", {{.*}})
|
|
|
|
# DBG_VALUE for variables "x", "y" and "z" are extended into %bb.9 from its
|
|
# predecessors %bb.0, %bb.2 and %bb.8.
|
|
# CHECK: bb.9.for.end:
|
|
# CHECK-DAG: DBG_VALUE $edi, $noreg, ![[X_VAR]], !DIExpression()
|
|
# CHECK-DAG: DBG_VALUE $esi, $noreg, ![[Y_VAR]], !DIExpression()
|
|
# CHECK-DAG: DBG_VALUE $edx, $noreg, ![[Z_VAR]], !DIExpression()
|
|
# CHECK: RET
|
|
|
|
--- |
|
|
; ModuleID = 'live-debug-values-3preds.ll'
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-linux-gnu"
|
|
|
|
; Function Attrs: norecurse nounwind readnone uwtable
|
|
define i32 @add(i32 %x, i32 %y, i32 %z, i32 %a) #0 !dbg !4 {
|
|
entry:
|
|
tail call void @llvm.dbg.value(metadata i32 %x, i64 0, metadata !9, metadata !17), !dbg !18
|
|
tail call void @llvm.dbg.value(metadata i32 %y, i64 0, metadata !10, metadata !17), !dbg !19
|
|
tail call void @llvm.dbg.value(metadata i32 %z, i64 0, metadata !11, metadata !17), !dbg !21
|
|
tail call void @llvm.dbg.value(metadata i32 %a, i64 0, metadata !12, metadata !17), !dbg !23
|
|
tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !13, metadata !17), !dbg !25
|
|
%mul = mul nsw i32 %y, %x, !dbg !26
|
|
%cmp.24 = icmp sgt i32 %mul, 0, !dbg !30
|
|
br i1 %cmp.24, label %for.body.preheader, label %for.end, !dbg !31
|
|
|
|
for.body.preheader: ; preds = %entry
|
|
br label %for.body, !dbg !32
|
|
|
|
for.cond: ; preds = %if.end.6
|
|
%cmp = icmp slt i32 %inc, %mul, !dbg !30
|
|
br i1 %cmp, label %for.body, label %for.end, !dbg !31
|
|
|
|
for.body: ; preds = %for.cond, %for.body.preheader
|
|
%i.025 = phi i32 [ %inc, %for.cond ], [ 0, %for.body.preheader ]
|
|
%0 = icmp sgt i32 %x, 0
|
|
br i1 %0, label %if.then, label %if.end, !dbg !35
|
|
|
|
if.then: ; preds = %for.body
|
|
%mul2 = mul nsw i32 %a, %x, !dbg !36
|
|
tail call void @llvm.dbg.value(metadata i32 %mul2, i64 0, metadata !12, metadata !17), !dbg !23
|
|
br label %for.end, !dbg !38
|
|
|
|
if.end: ; preds = %for.body
|
|
%1 = icmp sgt i32 %y, 0
|
|
br i1 %1, label %if.then.4, label %if.end.6, !dbg !39
|
|
|
|
if.then.4: ; preds = %if.end
|
|
%mul5 = mul nsw i32 %a, %y, !dbg !40
|
|
tail call void @llvm.dbg.value(metadata i32 %mul5, i64 0, metadata !12, metadata !17), !dbg !23
|
|
br label %for.end, !dbg !43
|
|
|
|
if.end.6: ; preds = %if.end
|
|
%2 = icmp sgt i32 %z, 0
|
|
%inc = add nuw nsw i32 %i.025, 1, !dbg !44
|
|
tail call void @llvm.dbg.value(metadata i32 %inc, i64 0, metadata !13, metadata !17), !dbg !25
|
|
br i1 %2, label %if.then.8, label %for.cond, !dbg !45
|
|
|
|
if.then.8: ; preds = %if.end.6
|
|
%mul9 = mul nsw i32 %a, %z, !dbg !46
|
|
tail call void @llvm.dbg.value(metadata i32 %mul9, i64 0, metadata !12, metadata !17), !dbg !23
|
|
br label %for.end, !dbg !49
|
|
|
|
for.end: ; preds = %for.cond, %if.then.8, %if.then.4, %if.then, %entry
|
|
%a.addr.0 = phi i32 [ %mul2, %if.then ], [ %mul5, %if.then.4 ], [ %mul9, %if.then.8 ], [ %a, %entry ], [ %a, %for.cond ]
|
|
ret i32 %a.addr.0, !dbg !50
|
|
}
|
|
|
|
; Function Attrs: nounwind readnone
|
|
declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
|
|
|
|
attributes #0 = { norecurse nounwind readnone uwtable }
|
|
attributes #1 = { nounwind readnone }
|
|
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!14, !15}
|
|
!llvm.ident = !{!16}
|
|
|
|
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 253049) ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
|
|
!1 = !DIFile(filename: "LiveDebugValues-3preds.c", directory: "/home/vt/julia/test/tvvikram")
|
|
!2 = !{}
|
|
!4 = distinct !DISubprogram(name: "add", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !8)
|
|
!5 = !DISubroutineType(types: !6)
|
|
!6 = !{!7, !7, !7, !7, !7}
|
|
!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
|
|
!8 = !{!9, !10, !11, !12, !13}
|
|
!9 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !1, line: 1, type: !7)
|
|
!10 = !DILocalVariable(name: "y", arg: 2, scope: !4, file: !1, line: 1, type: !7)
|
|
!11 = !DILocalVariable(name: "z", arg: 3, scope: !4, file: !1, line: 1, type: !7)
|
|
!12 = !DILocalVariable(name: "a", arg: 4, scope: !4, file: !1, line: 1, type: !7)
|
|
!13 = !DILocalVariable(name: "i", scope: !4, file: !1, line: 2, type: !7)
|
|
!14 = !{i32 2, !"Dwarf Version", i32 4}
|
|
!15 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!16 = !{!"clang version 3.8.0 (trunk 253049) "}
|
|
!17 = !DIExpression()
|
|
!18 = !DILocation(line: 1, column: 13, scope: !4)
|
|
!19 = !DILocation(line: 1, column: 20, scope: !20)
|
|
!20 = !DILexicalBlockFile(scope: !4, file: !1, discriminator: 1)
|
|
!21 = !DILocation(line: 1, column: 27, scope: !22)
|
|
!22 = !DILexicalBlockFile(scope: !4, file: !1, discriminator: 2)
|
|
!23 = !DILocation(line: 1, column: 34, scope: !24)
|
|
!24 = !DILexicalBlockFile(scope: !4, file: !1, discriminator: 3)
|
|
!25 = !DILocation(line: 2, column: 7, scope: !20)
|
|
!26 = !DILocation(line: 3, column: 21, scope: !27)
|
|
!27 = !DILexicalBlockFile(scope: !28, file: !1, discriminator: 1)
|
|
!28 = distinct !DILexicalBlock(scope: !29, file: !1, line: 3, column: 3)
|
|
!29 = distinct !DILexicalBlock(scope: !4, file: !1, line: 3, column: 3)
|
|
!30 = !DILocation(line: 3, column: 17, scope: !27)
|
|
!31 = !DILocation(line: 3, column: 3, scope: !27)
|
|
!32 = !DILocation(line: 4, column: 11, scope: !33)
|
|
!33 = distinct !DILexicalBlock(scope: !34, file: !1, line: 4, column: 9)
|
|
!34 = distinct !DILexicalBlock(scope: !28, file: !1, line: 3, column: 31)
|
|
!35 = !DILocation(line: 4, column: 9, scope: !34)
|
|
!36 = !DILocation(line: 5, column: 13, scope: !37)
|
|
!37 = distinct !DILexicalBlock(scope: !33, file: !1, line: 4, column: 16)
|
|
!38 = !DILocation(line: 6, column: 7, scope: !37)
|
|
!39 = !DILocation(line: 8, column: 9, scope: !34)
|
|
!40 = !DILocation(line: 9, column: 13, scope: !41)
|
|
!41 = distinct !DILexicalBlock(scope: !42, file: !1, line: 8, column: 16)
|
|
!42 = distinct !DILexicalBlock(scope: !34, file: !1, line: 8, column: 9)
|
|
!43 = !DILocation(line: 10, column: 7, scope: !41)
|
|
!44 = !DILocation(line: 3, column: 27, scope: !28)
|
|
!45 = !DILocation(line: 12, column: 9, scope: !34)
|
|
!46 = !DILocation(line: 13, column: 13, scope: !47)
|
|
!47 = distinct !DILexicalBlock(scope: !48, file: !1, line: 12, column: 16)
|
|
!48 = distinct !DILexicalBlock(scope: !34, file: !1, line: 12, column: 9)
|
|
!49 = !DILocation(line: 14, column: 7, scope: !47)
|
|
!50 = !DILocation(line: 17, column: 3, scope: !4)
|
|
|
|
...
|
|
---
|
|
name: add
|
|
alignment: 16
|
|
exposesReturnsTwice: false
|
|
tracksRegLiveness: true
|
|
liveins:
|
|
- { reg: '$edi' }
|
|
- { reg: '$esi' }
|
|
- { reg: '$edx' }
|
|
- { reg: '$ecx' }
|
|
frameInfo:
|
|
isFrameAddressTaken: false
|
|
isReturnAddressTaken: false
|
|
hasStackMap: false
|
|
hasPatchPoint: false
|
|
stackSize: 0
|
|
offsetAdjustment: 0
|
|
maxAlignment: 0
|
|
adjustsStack: false
|
|
hasCalls: false
|
|
maxCallFrameSize: 0
|
|
hasOpaqueSPAdjustment: false
|
|
hasVAStart: false
|
|
hasMustTailInVarArgFunc: false
|
|
body: |
|
|
bb.0.entry:
|
|
successors: %bb.1.for.body.preheader(20), %bb.9.for.end(12)
|
|
liveins: $ecx, $edi, $edx, $esi
|
|
|
|
DBG_VALUE $edi, _, !9, !17, debug-location !18
|
|
DBG_VALUE $esi, _, !10, !17, debug-location !19
|
|
DBG_VALUE $edx, _, !11, !17, debug-location !21
|
|
DBG_VALUE $ecx, _, !12, !17, debug-location !23
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
$r8d = MOV32rr $esi, debug-location !26
|
|
$r8d = IMUL32rr killed $r8d, $edi, implicit-def dead $eflags, debug-location !26
|
|
TEST32rr $r8d, $r8d, implicit-def $eflags, debug-location !31
|
|
JCC_1 %bb.9.for.end, 14, implicit $eflags
|
|
|
|
bb.1.for.body.preheader:
|
|
successors: %bb.3.for.body(0)
|
|
liveins: $ecx, $edi, $edx, $esi, $r8d
|
|
|
|
DBG_VALUE $edi, _, !9, !17, debug-location !18
|
|
DBG_VALUE $esi, _, !10, !17, debug-location !19
|
|
DBG_VALUE $edx, _, !11, !17, debug-location !21
|
|
DBG_VALUE $ecx, _, !12, !17, debug-location !23
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
$eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
|
|
|
|
bb.3.for.body (align 4):
|
|
successors: %bb.4.if.then(4), %bb.5.if.end(124)
|
|
liveins: $eax, $ecx, $edi, $edx, $esi, $r8d
|
|
|
|
DBG_VALUE $edi, _, !9, !17, debug-location !18
|
|
DBG_VALUE $esi, _, !10, !17, debug-location !19
|
|
DBG_VALUE $edx, _, !11, !17, debug-location !21
|
|
DBG_VALUE $ecx, _, !12, !17, debug-location !23
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
TEST32rr $edi, $edi, implicit-def $eflags, debug-location !35
|
|
JCC_1 %bb.4.if.then, 15, implicit $eflags
|
|
|
|
bb.5.if.end:
|
|
successors: %bb.6.if.then.4(4), %bb.7.if.end.6(124)
|
|
liveins: $eax, $ecx, $edi, $edx, $esi, $r8d
|
|
|
|
DBG_VALUE $edi, _, !9, !17, debug-location !18
|
|
DBG_VALUE $esi, _, !10, !17, debug-location !19
|
|
DBG_VALUE $edx, _, !11, !17, debug-location !21
|
|
DBG_VALUE $ecx, _, !12, !17, debug-location !23
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
TEST32rr $esi, $esi, implicit-def $eflags, debug-location !39
|
|
JCC_1 %bb.6.if.then.4, 15, implicit $eflags
|
|
|
|
bb.7.if.end.6:
|
|
successors: %bb.8.if.then.8(4), %bb.2.for.cond(124)
|
|
liveins: $eax, $ecx, $edi, $edx, $esi, $r8d
|
|
|
|
DBG_VALUE $edi, _, !9, !17, debug-location !18
|
|
DBG_VALUE $esi, _, !10, !17, debug-location !19
|
|
DBG_VALUE $edx, _, !11, !17, debug-location !21
|
|
DBG_VALUE $ecx, _, !12, !17, debug-location !23
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
TEST32rr $edx, $edx, implicit-def $eflags, debug-location !45
|
|
JCC_1 %bb.8.if.then.8, 15, implicit $eflags
|
|
|
|
bb.2.for.cond:
|
|
successors: %bb.3.for.body(124), %bb.9.for.end(4)
|
|
liveins: $eax, $ecx, $edi, $edx, $esi, $r8d
|
|
|
|
DBG_VALUE $edi, _, !9, !17, debug-location !18
|
|
DBG_VALUE $esi, _, !10, !17, debug-location !19
|
|
DBG_VALUE $edx, _, !11, !17, debug-location !21
|
|
DBG_VALUE $ecx, _, !12, !17, debug-location !23
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
$eax = INC32r killed $eax, implicit-def dead $eflags, debug-location !44
|
|
DBG_VALUE $eax, _, !13, !17, debug-location !25
|
|
CMP32rr $eax, $r8d, implicit-def $eflags, debug-location !31
|
|
JCC_1 %bb.3.for.body, 12, implicit $eflags
|
|
JMP_1 %bb.9.for.end
|
|
|
|
bb.4.if.then:
|
|
liveins: $ecx, $edi
|
|
|
|
DBG_VALUE $edi, _, !9, !17, debug-location !18
|
|
DBG_VALUE $ecx, _, !12, !17, debug-location !23
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
$ecx = IMUL32rr killed $ecx, killed $edi, implicit-def dead $eflags, debug-location !36
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
$eax = MOV32rr killed $ecx, debug-location !50
|
|
RETQ $eax, debug-location !50
|
|
|
|
bb.6.if.then.4:
|
|
liveins: $ecx, $esi
|
|
|
|
DBG_VALUE $esi, _, !10, !17, debug-location !19
|
|
DBG_VALUE $ecx, _, !12, !17, debug-location !23
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
$ecx = IMUL32rr killed $ecx, killed $esi, implicit-def dead $eflags, debug-location !40
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
$eax = MOV32rr killed $ecx, debug-location !50
|
|
RETQ $eax, debug-location !50
|
|
|
|
bb.8.if.then.8:
|
|
successors: %bb.9.for.end(0)
|
|
liveins: $ecx, $edx
|
|
|
|
DBG_VALUE $edx, _, !11, !17, debug-location !21
|
|
DBG_VALUE $ecx, _, !12, !17, debug-location !23
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
$ecx = IMUL32rr killed $ecx, killed $edx, implicit-def dead $eflags, debug-location !46
|
|
|
|
bb.9.for.end:
|
|
liveins: $ecx
|
|
|
|
DBG_VALUE 0, 0, !13, !17, debug-location !25
|
|
$eax = MOV32rr killed $ecx, debug-location !50
|
|
RETQ $eax, debug-location !50
|
|
|
|
...
|