Files
clang-p2996/llvm/test/DebugInfo/MIR/X86/live-debug-values-restore.mir
Jeremy Morse 61800a75b7 [DebugInfo] LiveDebugValues: move DBG_VALUE creation into VarLoc class
Rather than having a mixture of location-state shared between DBG_VALUEs
and VarLoc objects in LiveDebugValues, this patch makes VarLoc the
master record of variable locations. The refactoring means that the
transfer of locations from one place to another is always a performed by
an operation on an existing VarLoc, that produces another transferred
VarLoc. DBG_VALUEs are only created at the end of LiveDebugValues, once
all locations are known. As a plus, there is now only one method where
DBG_VALUEs can be created.

The test case added covers a circumstance that is now impossible to
express in LiveDebugValues: if an already-indirect DBG_VALUE is spilt,
previously it would have been restored-from-spill as a direct DBG_VALUE.
We now don't lose this information along the way, as VarLocs always
refer back to the "original" non-transfer DBG_VALUE, and we can always
work out whether a location was "originally" indirect.

Differential Revision: https://reviews.llvm.org/D67398

llvm-svn: 373727
2019-10-04 10:53:47 +00:00

737 lines
38 KiB
YAML

# RUN: llc -run-pass livedebugvalues -march=x86-64 -o - %s | FileCheck %s
# Generated from the following source with:
# clang -g -mllvm -stop-before=livedebugvalues -S -O2 test.c -o test.mir
# Then more functions added to test for extra behaviours with complex
# expressions:
# 'g': test for a crash from PR42773
# 'h': complex expressions should be restored
# 'i': spills should be restored across block boundaries
# 'j': indirect DBG_VALUEs should be indirect after restoration
# #define FORCE_SPILL() \
# __asm volatile("" : : : \
# "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "r8", \
# "r9", "r10", "r11", "r12", "r13", "r14", "r15")
# int f(int *p) {
# if (p) {
# FORCE_SPILL();
# }
# return *(p + 1);
# }
# Pick out DILocalVariable numbers for "p", "q" and "r" etc
# CHECK: ![[PVAR:[0-9]+]] = !DILocalVariable(name: "p",
# CHECK: ![[QVAR:[0-9]+]] = !DILocalVariable(name: "q",
# CHECK: ![[RVAR:[0-9]+]] = !DILocalVariable(name: "r",
# CHECK: ![[SVAR:[0-9]+]] = !DILocalVariable(name: "s",
# CHECK: ![[TVAR:[0-9]+]] = !DILocalVariable(name: "t",
# Ascertain that the spill has been recognized and manifested in a DBG_VALUE.
# CHECK: MOV64mr $rsp,{{.*-8.*}}killed{{.*}}$rdi :: (store 8 into %stack.0)
# CHECK-NEXT: DBG_VALUE $rsp,{{.*}}![[PVAR]],{{.*}}!DIExpression(DW_OP_constu, 8, DW_OP_minus)
# Check for the restore.
# CHECK: $rdi = MOV64rm $rsp,{{.*-8.*}}:: (load 8 from %stack.0)
# CHECK-NEXT: DBG_VALUE $rdi,{{.*}}![[PVAR]], !DIExpression()
--- |
define dso_local i32 @f(i32* readonly %p) local_unnamed_addr !dbg !7 {
entry:
call void @llvm.dbg.value(metadata i32* %p, metadata !13, metadata !DIExpression()), !dbg !14
%tobool = icmp eq i32* %p, null, !dbg !15
br i1 %tobool, label %if.end, label %if.then, !dbg !17
if.then: ; preds = %entry
tail call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"(), !dbg !18, !srcloc !20
br label %if.end, !dbg !21
if.end: ; preds = %entry, %if.then
%add.ptr = getelementptr inbounds i32, i32* %p, i64 1, !dbg !22
%0 = load i32, i32* %add.ptr, align 4, !dbg !23, !tbaa !24
ret i32 %0, !dbg !28
}
define dso_local i32 @g(i32* readonly %p) local_unnamed_addr !dbg !107 {
entry:
call void @llvm.dbg.value(metadata i32* %p, metadata !113, metadata !DIExpression()), !dbg !114
%tobool = icmp eq i32* %p, null, !dbg !115
br i1 %tobool, label %if.end, label %if.then, !dbg !117
if.then: ; preds = %entry
tail call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"(), !dbg !118, !srcloc !120
br label %if.end, !dbg !121
if.end: ; preds = %entry, %if.then
%add.ptr = getelementptr inbounds i32, i32* %p, i64 1, !dbg !122
%0 = load i32, i32* %add.ptr, align 4, !dbg !123, !tbaa !24
ret i32 %0, !dbg !128
}
define dso_local i32 @h(i32* readonly %p) local_unnamed_addr !dbg !207 {
entry:
call void @llvm.dbg.value(metadata i32* %p, metadata !213, metadata !DIExpression()), !dbg !214
%tobool = icmp eq i32* %p, null, !dbg !215
br i1 %tobool, label %if.end, label %if.then, !dbg !217
if.then: ; preds = %entry
tail call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"(), !dbg !218, !srcloc !220
br label %if.end, !dbg !221
if.end: ; preds = %entry, %if.then
%add.ptr = getelementptr inbounds i32, i32* %p, i64 1, !dbg !222
%0 = load i32, i32* %add.ptr, align 4, !dbg !223, !tbaa !24
ret i32 %0, !dbg !228
}
define dso_local i32 @i(i32* readonly %p) local_unnamed_addr !dbg !307 {
entry:
br label %foo
foo:
call void @llvm.dbg.value(metadata i32* %p, metadata !313, metadata !DIExpression()), !dbg !314
%tobool = icmp eq i32* %p, null, !dbg !315
br i1 %tobool, label %if.end, label %if.then, !dbg !317
if.then: ; preds = %entry
tail call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"(), !dbg !318, !srcloc !320
br label %if.end, !dbg !321
if.end: ; preds = %entry, %if.then
%add.ptr = getelementptr inbounds i32, i32* %p, i64 1, !dbg !322
%0 = load i32, i32* %add.ptr, align 4, !dbg !323, !tbaa !24
ret i32 %0, !dbg !328
}
define dso_local i32 @j(i32* readonly %p) local_unnamed_addr !dbg !402 {
entry:
br label %foo
foo:
call void @llvm.dbg.value(metadata i32* %p, metadata !404, metadata !DIExpression()), !dbg !405
%tobool = icmp eq i32* %p, null, !dbg !406
br i1 %tobool, label %if.end, label %if.then, !dbg !408
if.then: ; preds = %entry
tail call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"(), !dbg !409, !srcloc !411
br label %if.end, !dbg !412
if.end: ; preds = %entry, %if.then
%add.ptr = getelementptr inbounds i32, i32* %p, i64 1, !dbg !413
%0 = load i32, i32* %add.ptr, align 4, !dbg !414, !tbaa !24
ret i32 %0, !dbg !415
}
declare void @llvm.dbg.value(metadata, metadata, metadata)
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 (https://git.llvm.org/git/clang.git/ 57a6ce7ac318de98e3e777e09cb9ed8282b5cc03) (https://git.llvm.org/git/llvm.git/ ff54a19e4912d7f15cb02798a7f2048441bff751)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
!1 = !DIFile(filename: "test2.c", directory: "/home/test")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 9.0.0 (https://git.llvm.org/git/clang.git/ 57a6ce7ac318de98e3e777e09cb9ed8282b5cc03) (https://git.llvm.org/git/llvm.git/ ff54a19e4912d7f15cb02798a7f2048441bff751)"}
!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
!8 = !DISubroutineType(types: !9)
!9 = !{!10, !11}
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64)
!12 = !{!13}
!13 = !DILocalVariable(name: "p", arg: 1, scope: !7, file: !1, line: 5, type: !11)
!14 = !DILocation(line: 5, column: 12, scope: !7)
!15 = !DILocation(line: 6, column: 7, scope: !16)
!16 = distinct !DILexicalBlock(scope: !7, file: !1, line: 6, column: 7)
!17 = !DILocation(line: 6, column: 7, scope: !7)
!18 = !DILocation(line: 7, column: 5, scope: !19)
!19 = distinct !DILexicalBlock(scope: !16, file: !1, line: 6, column: 10)
!20 = !{i32 -2147471544}
!21 = !DILocation(line: 8, column: 3, scope: !19)
!22 = !DILocation(line: 9, column: 14, scope: !7)
!23 = !DILocation(line: 9, column: 10, scope: !7)
!24 = !{!25, !25, i64 0}
!25 = !{!"int", !26, i64 0}
!26 = !{!"omnipotent char", !27, i64 0}
!27 = !{!"Simple C/C++ TBAA"}
!28 = !DILocation(line: 9, column: 3, scope: !7)
!101 = !DIBasicType(name: "looong int", size: 64, encoding: DW_ATE_signed)
!107 = distinct !DISubprogram(name: "g", scope: !0, file: !1, line: 105, type: !8, scopeLine: 105, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !112)
!112 = !{!113}
!113 = !DILocalVariable(name: "q", arg: 1, scope: !107, file: !1, line: 105, type: !101)
!114 = !DILocation(line: 105, column: 12, scope: !107)
!115 = !DILocation(line: 106, column: 7, scope: !116)
!116 = distinct !DILexicalBlock(scope: !107, file: !1, line: 106, column: 7)
!117 = !DILocation(line: 106, column: 7, scope: !107)
!118 = !DILocation(line: 107, column: 5, scope: !119)
!119 = distinct !DILexicalBlock(scope: !116, file: !1, line: 106, column: 10)
!120 = !{i32 -2147471544}
!121 = !DILocation(line: 108, column: 3, scope: !119)
!122 = !DILocation(line: 109, column: 14, scope: !107)
!123 = !DILocation(line: 109, column: 10, scope: !107)
!128 = !DILocation(line: 109, column: 3, scope: !107)
!201 = !DIBasicType(name: "looong int", size: 64, encoding: DW_ATE_signed)
!207 = distinct !DISubprogram(name: "g", scope: !0, file: !1, line: 105, type: !8, scopeLine: 105, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !212)
!212 = !{!213}
!213 = !DILocalVariable(name: "r", arg: 1, scope: !207, file: !1, line: 105, type: !201)
!214 = !DILocation(line: 105, column: 12, scope: !207)
!215 = !DILocation(line: 106, column: 7, scope: !216)
!216 = distinct !DILexicalBlock(scope: !207, file: !1, line: 106, column: 7)
!217 = !DILocation(line: 106, column: 7, scope: !207)
!218 = !DILocation(line: 107, column: 5, scope: !219)
!219 = distinct !DILexicalBlock(scope: !216, file: !1, line: 106, column: 10)
!220 = !{i32 -2147471544}
!221 = !DILocation(line: 108, column: 3, scope: !219)
!222 = !DILocation(line: 109, column: 14, scope: !207)
!223 = !DILocation(line: 109, column: 10, scope: !207)
!228 = !DILocation(line: 109, column: 3, scope: !207)
!301 = !DIBasicType(name: "looong int", size: 64, encoding: DW_ATE_signed)
!307 = distinct !DISubprogram(name: "g", scope: !0, file: !1, line: 105, type: !8, scopeLine: 105, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !312)
!312 = !{!313}
!313 = !DILocalVariable(name: "s", arg: 1, scope: !307, file: !1, line: 105, type: !301)
!314 = !DILocation(line: 105, column: 12, scope: !307)
!315 = !DILocation(line: 106, column: 7, scope: !316)
!316 = distinct !DILexicalBlock(scope: !307, file: !1, line: 106, column: 7)
!317 = !DILocation(line: 106, column: 7, scope: !307)
!318 = !DILocation(line: 107, column: 5, scope: !319)
!319 = distinct !DILexicalBlock(scope: !316, file: !1, line: 106, column: 10)
!320 = !{i32 -2147471544}
!321 = !DILocation(line: 108, column: 3, scope: !319)
!322 = !DILocation(line: 109, column: 14, scope: !307)
!323 = !DILocation(line: 109, column: 10, scope: !307)
!328 = !DILocation(line: 109, column: 3, scope: !307)
!401 = !DIBasicType(name: "looong int", size: 64, encoding: DW_ATE_signed)
!402 = distinct !DISubprogram(name: "j", scope: !0, file: !1, line: 105, type: !8, scopeLine: 105, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !403)
!403 = !{!404}
!404 = !DILocalVariable(name: "t", arg: 1, scope: !402, file: !1, line: 105, type: !401)
!405 = !DILocation(line: 105, column: 12, scope: !402)
!406 = !DILocation(line: 106, column: 7, scope: !407)
!407 = distinct !DILexicalBlock(scope: !402, file: !1, line: 106, column: 7)
!408 = !DILocation(line: 106, column: 7, scope: !402)
!409 = !DILocation(line: 107, column: 5, scope: !410)
!410 = distinct !DILexicalBlock(scope: !407, file: !1, line: 106, column: 10)
!411 = !{i32 -2147471544}
!412 = !DILocation(line: 108, column: 3, scope: !410)
!413 = !DILocation(line: 109, column: 14, scope: !402)
!414 = !DILocation(line: 109, column: 10, scope: !402)
!415 = !DILocation(line: 109, column: 3, scope: !402)
...
---
name: f
alignment: 16
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
failedISel: false
tracksRegLiveness: true
hasWinCFI: false
registers: []
liveins:
- { reg: '$rdi', virtual-reg: '' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 48
offsetAdjustment: -48
maxAlignment: 8
adjustsStack: false
hasCalls: false
stackProtector: ''
maxCallFrameSize: 0
cvBytesOfCalleeSavedRegisters: 48
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
localFrameSize: 0
savePoint: ''
restorePoint: ''
fixedStack:
- { id: 0, type: spill-slot, offset: -56, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$rbx', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 1, type: spill-slot, offset: -48, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$r12', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 2, type: spill-slot, offset: -40, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$r13', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 3, type: spill-slot, offset: -32, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$r14', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 4, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$r15', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 5, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$rbp', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
stack:
- { id: 0, name: '', type: spill-slot, offset: -64, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
constants: []
body: |
bb.0.entry:
successors: %bb.2(0x30000000), %bb.1(0x50000000)
liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
DBG_VALUE $rdi, $noreg, !13, !DIExpression(), debug-location !14
DBG_VALUE $rdi, $noreg, !13, !DIExpression(), debug-location !14
TEST64rr renamable $rdi, renamable $rdi, implicit-def $eflags, debug-location !15
JCC_1 %bb.2, 4, implicit $eflags, debug-location !17
bb.1.if.then:
successors: %bb.2(0x80000000)
liveins: $rdi, $rbp, $r15, $r14, $r13, $r12, $rbx
frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 16
frame-setup PUSH64r killed $r15, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 24
frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 32
frame-setup PUSH64r killed $r13, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 40
frame-setup PUSH64r killed $r12, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 48
frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 56
CFI_INSTRUCTION offset $rbx, -56
CFI_INSTRUCTION offset $r12, -48
CFI_INSTRUCTION offset $r13, -40
CFI_INSTRUCTION offset $r14, -32
CFI_INSTRUCTION offset $r15, -24
CFI_INSTRUCTION offset $rbp, -16
MOV64mr $rsp, 1, $noreg, -8, $noreg, killed renamable $rdi :: (store 8 into %stack.0)
INLINEASM &"", 1, 12, implicit-def dead early-clobber $rax, 12, implicit-def dead early-clobber $rbx, 12, implicit-def dead early-clobber $rcx, 12, implicit-def dead early-clobber $rdx, 12, implicit-def dead early-clobber $rsi, 12, implicit-def dead early-clobber $rdi, 12, implicit-def dead early-clobber $rbp, 12, implicit-def dead early-clobber $r8, 12, implicit-def dead early-clobber $r9, 12, implicit-def dead early-clobber $r10, 12, implicit-def dead early-clobber $r11, 12, implicit-def dead early-clobber $r12, 12, implicit-def dead early-clobber $r13, 12, implicit-def dead early-clobber $r14, 12, implicit-def dead early-clobber $r15, 12, implicit-def dead early-clobber $eflags, !20, debug-location !18
renamable $rdi = MOV64rm $rsp, 1, $noreg, -8, $noreg :: (load 8 from %stack.0)
$rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 48
$r12 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 40
$r13 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 32
$r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 24
$r15 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 16
$rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 8
bb.2.if.end:
liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
renamable $eax = MOV32rm killed renamable $rdi, 1, $noreg, 4, $noreg, debug-location !23 :: (load 4 from %ir.add.ptr, !tbaa !24)
RETQ $eax, debug-location !28
...
---
# This second function has been appended as a regression test against a
# crash, caused by expressions being created from spill restores that did
# not preserve fragment information. Test that no empty expressions are
# created at all, and the last block describes both variable fragments.
# CHECK-LABEL: name: g
# CHECK-NOT: !DIExpression()
# CHECK-LABEL: bb.2.if.end:
# CHECK: DBG_VALUE $rdi, $noreg, ![[QVAR]], !DIExpression(DW_OP_LLVM_fragment, 0, 32)
# CHECK-NEXT: DBG_VALUE $rbx, $noreg, ![[QVAR]], !DIExpression(DW_OP_LLVM_fragment, 32, 32)
name: g
alignment: 16
tracksRegLiveness: true
liveins:
- { reg: '$rdi', virtual-reg: '' }
frameInfo:
stackSize: 48
offsetAdjustment: -48
maxAlignment: 8
cvBytesOfCalleeSavedRegisters: 48
localFrameSize: 0
fixedStack:
- { id: 0, type: spill-slot, offset: -56, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$rbx', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 1, type: spill-slot, offset: -48, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$r12', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 2, type: spill-slot, offset: -40, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$r13', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 3, type: spill-slot, offset: -32, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$r14', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 4, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$r15', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 5, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$rbp', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
stack:
- { id: 0, name: '', type: spill-slot, offset: -64, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
constants: []
body: |
bb.0.entry:
successors: %bb.1(0x50000000)
liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
DBG_VALUE $rdi, $noreg, !113, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !114
TEST64rr renamable $rdi, renamable $rdi, implicit-def $eflags, debug-location !115
JMP_1 %bb.1, implicit $eflags, debug-location !117
bb.1.if.then:
successors: %bb.2(0x80000000)
liveins: $rdi, $rbp, $r15, $r14, $r13, $r12, $rbx
MOV64mr $rsp, 1, $noreg, -8, $noreg, killed renamable $rdi :: (store 8 into %stack.0)
renamable $rdi = MOV64rm $rsp, 1, $noreg, -8, $noreg :: (load 8 from %stack.0)
bb.2.if.end:
liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
DBG_VALUE $rbx, $noreg, !113, !DIExpression(DW_OP_LLVM_fragment, 32, 32), debug-location !114
MOV64mr $rsp, 1, $noreg, -8, $noreg, killed renamable $rbx :: (store 8 into %stack.0)
renamable $rsi = MOV64rm $rsp, 1, $noreg, -8, $noreg :: (load 8 from %stack.0)
renamable $eax = MOV32rm killed renamable $rsi, 1, $noreg, 4, $noreg, debug-location !123 :: (load 4 from %ir.add.ptr, !tbaa !24)
$rdi = MOV64ri 0
RETQ $eax, debug-location !128
...
---
# This third function tests that complex expressions are spilt, and restored
# correctly within a basic block.
# FIXME: the spilt location below is wrong, there should be a deref between
# the spill-offset and the DW_OP_plus_uconst.
# CHECK-LABEL: name: h
# CHECK-LABEL: bb.0.entry:
# CHECK: DBG_VALUE $rdi, $noreg, ![[RVAR]], !DIExpression(DW_OP_plus_uconst, 1)
# CHECK-LABEL: bb.1.if.then:
# CHECK: DBG_VALUE $rdi, $noreg, ![[RVAR]], !DIExpression(DW_OP_plus_uconst, 1)
# CHECK: DBG_VALUE $rsp, 0, ![[RVAR]], !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_plus_uconst, 1)
# CHECK: DBG_VALUE $rdi, $noreg, ![[RVAR]], !DIExpression(DW_OP_plus_uconst, 1)
# CHECK-LABEL: bb.2.if.end:
# CHECK: DBG_VALUE $rdi, $noreg, ![[RVAR]], !DIExpression(DW_OP_plus_uconst, 1)
name: h
alignment: 16
tracksRegLiveness: true
liveins:
- { reg: '$rdi', virtual-reg: '' }
frameInfo:
stackSize: 48
offsetAdjustment: -48
maxAlignment: 8
cvBytesOfCalleeSavedRegisters: 48
localFrameSize: 0
fixedStack:
- { id: 0, type: spill-slot, offset: -56, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$rbx', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 1, type: spill-slot, offset: -48, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$r12', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 2, type: spill-slot, offset: -40, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$r13', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 3, type: spill-slot, offset: -32, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$r14', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 4, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$r15', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 5, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$rbp', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
stack:
- { id: 0, name: '', type: spill-slot, offset: -64, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
constants: []
body: |
bb.0.entry:
successors: %bb.2(0x30000000), %bb.1(0x50000000)
liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
DBG_VALUE $rdi, $noreg, !213, !DIExpression(DW_OP_plus_uconst, 1), debug-location !214
TEST64rr renamable $rdi, renamable $rdi, implicit-def $eflags, debug-location !215
JCC_1 %bb.2, 4, implicit $eflags, debug-location !217
bb.1.if.then:
successors: %bb.2(0x80000000)
liveins: $rdi, $rbp, $r15, $r14, $r13, $r12, $rbx
frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 16
frame-setup PUSH64r killed $r15, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 24
frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 32
frame-setup PUSH64r killed $r13, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 40
frame-setup PUSH64r killed $r12, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 48
frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 56
CFI_INSTRUCTION offset $rbx, -56
CFI_INSTRUCTION offset $r12, -48
CFI_INSTRUCTION offset $r13, -40
CFI_INSTRUCTION offset $r14, -32
CFI_INSTRUCTION offset $r15, -24
CFI_INSTRUCTION offset $rbp, -16
MOV64mr $rsp, 1, $noreg, -8, $noreg, killed renamable $rdi :: (store 8 into %stack.0)
INLINEASM &"", 1, 12, implicit-def dead early-clobber $rax, 12, implicit-def dead early-clobber $rbx, 12, implicit-def dead early-clobber $rcx, 12, implicit-def dead early-clobber $rdx, 12, implicit-def dead early-clobber $rsi, 12, implicit-def dead early-clobber $rdi, 12, implicit-def dead early-clobber $rbp, 12, implicit-def dead early-clobber $r8, 12, implicit-def dead early-clobber $r9, 12, implicit-def dead early-clobber $r10, 12, implicit-def dead early-clobber $r11, 12, implicit-def dead early-clobber $r12, 12, implicit-def dead early-clobber $r13, 12, implicit-def dead early-clobber $r14, 12, implicit-def dead early-clobber $r15, 12, implicit-def dead early-clobber $eflags, !220, debug-location !218
renamable $rdi = MOV64rm $rsp, 1, $noreg, -8, $noreg :: (load 8 from %stack.0)
$rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 48
$r12 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 40
$r13 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 32
$r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 24
$r15 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 16
$rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 8
bb.2.if.end:
liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
renamable $eax = MOV32rm killed renamable $rdi, 1, $noreg, 4, $noreg, debug-location !223 :: (load 4 from %ir.add.ptr, !tbaa !24)
RETQ $eax, debug-location !228
...
---
# Function four: test that spill restores are detected across block
# boundaries. The spill has been moved to bb.1, children of which are
# bb 2 and 3, neither of which modifies the stack loc. The exit block (3)
# should still be tracking the spill, and restore it on stack load.
# FIXME: this test too contains a broken spill location.
# Summary: loc is in $rdi in bb0, spills to stack in bb1, remains in stack
# in bb2, starts in stack then loaded in bb3.
# CHECK-LABEL: name: i
# CHECK-LABEL: bb.0.entry:
# CHECK: DBG_VALUE $rdi, $noreg, ![[SVAR]], !DIExpression(DW_OP_plus_uconst, 1)
# CHECK-LABEL: bb.1.foo:
# CHECK: DBG_VALUE $rdi, $noreg, ![[SVAR]], !DIExpression(DW_OP_plus_uconst, 1)
# CHECK: DBG_VALUE $rsp, 0, ![[SVAR]], !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_plus_uconst, 1)
# CHECK-LABEL: bb.2.if.then:
# CHECK: DBG_VALUE $rsp, 0, ![[SVAR]], !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_plus_uconst, 1)
# CHECK-LABEL: bb.3.if.end
# CHECK: DBG_VALUE $rsp, 0, ![[SVAR]], !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_plus_uconst, 1)
# CHECK: DBG_VALUE $rdi, $noreg, ![[SVAR]], !DIExpression(DW_OP_plus_uconst, 1)
name: i
alignment: 16
tracksRegLiveness: true
liveins:
- { reg: '$rdi', virtual-reg: '' }
frameInfo:
stackSize: 48
offsetAdjustment: -48
maxAlignment: 8
cvBytesOfCalleeSavedRegisters: 48
localFrameSize: 0
fixedStack:
- { id: 0, type: spill-slot, offset: -56, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$rbx', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 1, type: spill-slot, offset: -48, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$r12', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 2, type: spill-slot, offset: -40, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$r13', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 3, type: spill-slot, offset: -32, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$r14', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 4, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$r15', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 5, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$rbp', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
stack:
- { id: 0, name: '', type: spill-slot, offset: -64, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
constants: []
body: |
bb.0.entry:
successors: %bb.1
liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
DBG_VALUE $rdi, $noreg, !313, !DIExpression(DW_OP_plus_uconst, 1), debug-location !314
JMP_1 %bb.1, debug-location !317
bb.1.foo:
successors: %bb.3(0x30000000), %bb.2(0x50000000)
liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
$rax = COPY $rdi
MOV64mr $rsp, 1, $noreg, -8, $noreg, killed renamable $rdi :: (store 8 into %stack.0)
$rdi = MOV64ri 0
TEST64rr $rax, renamable $rax, implicit-def $eflags, debug-location !315
JCC_1 %bb.3, 4, implicit $eflags, debug-location !317
bb.2.if.then:
successors: %bb.3(0x80000000)
liveins: $rbp, $r15, $r14, $r13, $r12, $rbx
frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 16
frame-setup PUSH64r killed $r15, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 24
frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 32
frame-setup PUSH64r killed $r13, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 40
frame-setup PUSH64r killed $r12, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 48
frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 56
CFI_INSTRUCTION offset $rbx, -56
CFI_INSTRUCTION offset $r12, -48
CFI_INSTRUCTION offset $r13, -40
CFI_INSTRUCTION offset $r14, -32
CFI_INSTRUCTION offset $r15, -24
CFI_INSTRUCTION offset $rbp, -16
INLINEASM &"", 1, 12, implicit-def dead early-clobber $rax, 12, implicit-def dead early-clobber $rbx, 12, implicit-def dead early-clobber $rcx, 12, implicit-def dead early-clobber $rdx, 12, implicit-def dead early-clobber $rsi, 12, implicit-def dead early-clobber $rdi, 12, implicit-def dead early-clobber $rbp, 12, implicit-def dead early-clobber $r8, 12, implicit-def dead early-clobber $r9, 12, implicit-def dead early-clobber $r10, 12, implicit-def dead early-clobber $r11, 12, implicit-def dead early-clobber $r12, 12, implicit-def dead early-clobber $r13, 12, implicit-def dead early-clobber $r14, 12, implicit-def dead early-clobber $r15, 12, implicit-def dead early-clobber $eflags, !320, debug-location !318
$rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 48
$r12 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 40
$r13 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 32
$r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 24
$r15 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 16
$rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 8
bb.3.if.end:
liveins: $rbx, $r12, $r13, $r14, $r15, $rbp
renamable $rdi = MOV64rm $rsp, 1, $noreg, -8, $noreg :: (load 8 from %stack.0)
renamable $eax = MOV32rm killed renamable $rdi, 1, $noreg, 4, $noreg, debug-location !323 :: (load 4 from %ir.add.ptr, !tbaa !24)
RETQ $eax, debug-location !328
...
---
# Test that if an unspilt DBG_VALUE starts as an indirect DBG_VALUE, then it
# is restored as an indirect DBG_VALUE. FIXME: Note that for the intervening
# period of being a spilt location there is still a missing layer of
# indirection.
# CHECK-LABEL: name: j
# CHECK-LABEL: bb.0.entry:
# CHECK: DBG_VALUE $rdi, 0, ![[TVAR]], !DIExpression()
# CHECK-LABEL: bb.1.if.then:
# CHECK: DBG_VALUE $rsp, 0, ![[TVAR]], !DIExpression(DW_OP_constu, 8, DW_OP_minus)
# CHECK: INLINEASM
# CHECK: DBG_VALUE ${{[a-zA-Z0-9]+}}, 0, ![[TVAR]], !DIExpression()
# CHECK-LABEL: bb.2.if.end
name: j
tracksRegLiveness: true
liveins:
- { reg: '$rdi', virtual-reg: '' }
frameInfo:
stackSize: 48
offsetAdjustment: -48
maxAlignment: 8
cvBytesOfCalleeSavedRegisters: 48
fixedStack:
- { id: 0, type: spill-slot, offset: -56, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$rbx', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 1, type: spill-slot, offset: -48, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$r12', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 2, type: spill-slot, offset: -40, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$r13', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 3, type: spill-slot, offset: -32, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$r14', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 4, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: default,
callee-saved-register: '$r15', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
- { id: 5, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$rbp', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
stack:
- { id: 0, name: '', type: spill-slot, offset: -64, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
constants: []
body: |
bb.0.entry:
successors: %bb.2, %bb.1
liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
DBG_VALUE $rdi, 0, !404, !DIExpression(), debug-location !405
DBG_VALUE $rdi, 0, !404, !DIExpression(), debug-location !405
TEST64rr renamable $rdi, renamable $rdi, implicit-def $eflags, debug-location !406
JCC_1 %bb.2, 4, implicit $eflags, debug-location !408
bb.1.if.then:
successors: %bb.2
liveins: $rdi, $rbp, $r15, $r14, $r13, $r12, $rbx
frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 16
frame-setup PUSH64r killed $r15, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 24
frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 32
frame-setup PUSH64r killed $r13, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 40
frame-setup PUSH64r killed $r12, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 48
frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 56
CFI_INSTRUCTION offset $rbx, -56
CFI_INSTRUCTION offset $r12, -48
CFI_INSTRUCTION offset $r13, -40
CFI_INSTRUCTION offset $r14, -32
CFI_INSTRUCTION offset $r15, -24
CFI_INSTRUCTION offset $rbp, -16
MOV64mr $rsp, 1, $noreg, -8, $noreg, killed renamable $rdi :: (store 8 into %stack.0)
INLINEASM &"", 1, 12, implicit-def dead early-clobber $rax, 12, implicit-def dead early-clobber $rbx, 12, implicit-def dead early-clobber $rcx, 12, implicit-def dead early-clobber $rdx, 12, implicit-def dead early-clobber $rsi, 12, implicit-def dead early-clobber $rdi, 12, implicit-def dead early-clobber $rbp, 12, implicit-def dead early-clobber $r8, 12, implicit-def dead early-clobber $r9, 12, implicit-def dead early-clobber $r10, 12, implicit-def dead early-clobber $r11, 12, implicit-def dead early-clobber $r12, 12, implicit-def dead early-clobber $r13, 12, implicit-def dead early-clobber $r14, 12, implicit-def dead early-clobber $r15, 12, implicit-def dead early-clobber $eflags, !20, debug-location !409
renamable $rdi = MOV64rm $rsp, 1, $noreg, -8, $noreg :: (load 8 from %stack.0)
$rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 48
$r12 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 40
$r13 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 32
$r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 24
$r15 = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 16
$rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 8
bb.2.if.end:
liveins: $rdi, $rbx, $r12, $r13, $r14, $r15, $rbp
renamable $eax = MOV32rm killed renamable $rdi, 1, $noreg, 4, $noreg, debug-location !414 :: (load 4 from %ir.add.ptr, !tbaa !24)
RETQ $eax, debug-location !415
...