Files
clang-p2996/llvm/test/DebugInfo/MIR/X86/live-debug-values-entry-transfer.mir
Jeremy Morse 313d2ce999 [DebugInfo] LiveDebugValues should always revisit backedges if it skips them
The "join" method in LiveDebugValues does not attempt to join unseen
predecessor blocks if their out-locations aren't yet initialized, instead
the block should be re-visited later to see if any locations have changed
validity. However, because the set of blocks were all being "process"'d
once before "join" saw them, that logic in "join" was actually ignoring
legitimate out-locations on the first pass through. This meant that some
invalidated locations were not removed from the head of loops, allowing
illegal locations to persist.

Fix this by removing the run of "process" before the main join/process loop
in ExtendRanges. Now the unseen predecessors that "join" skips truly are
uninitialized, and we come back to the block at a later time to re-run
"join", see the @baz function added.

This also fixes another fault where stack/register transfers in the entry
block (or any other before-any-loop-block) had their tranfers initially
ignored, and were then never revisited. The MIR test added tests for this
behaviour.

XFail a test that exposes another bug; a fix for this is coming in D66895.

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

llvm-svn: 370328
2019-08-29 10:53:29 +00:00

123 lines
4.0 KiB
YAML

# RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown | FileCheck %s
#
# In this lightly modified test case, the transfer in the entry block from
# geti32's return value in $eax to the non-volatile $ebx should be recognized,
# and propagated throughout the whole function.
#
# CHECK-LABEL: bb.0.entry
# CHECK: DBG_VALUE $eax
# CHECK: DBG_VALUE $ebx
# CHECK-LABEL: bb.1.loop2
# CHECK: DBG_VALUE $ebx
# CHECK-LABEL: bb.2.loop
# CHECK: DBG_VALUE $ebx
# CHECK-LABEL: bb.3.exit
# CHECK: DBG_VALUE $ebx
--- |
; ModuleID = 'asdf'
source_filename = "asdf.ll"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-unknown"
@glob = global i32 0
declare i1 @booler()
declare i32 @geti32()
declare void @escape(i32)
; Function Attrs: nounwind readnone speculatable willreturn
declare void @llvm.dbg.value(metadata, metadata, metadata)
define i32 @foo() !dbg !4 {
entry:
%bar = call i32 @geti32(), !dbg !10
call void @llvm.dbg.value(metadata i32 %bar, metadata !9, metadata !DIExpression()), !dbg !10
br label %loop
loop: ; preds = %loop2, %entry
call void @escape(i32 %bar)
%retval = call i1 @booler(), !dbg !10
br i1 %retval, label %loop2, label %exit
loop2: ; preds = %loop
store i32 %bar, i32* @glob
br label %loop
exit: ; preds = %loop
ret i32 %bar
}
; Function Attrs: nounwind
declare void @llvm.stackprotector(i8*, i8**)
!llvm.module.flags = !{!0, !1}
!llvm.dbg.cu = !{!2}
!0 = !{i32 2, !"Debug Info Version", i32 3}
!1 = !{i32 2, !"Dwarf Version", i32 4}
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "beards", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
!3 = !DIFile(filename: "bees.cpp", directory: ".")
!4 = distinct !DISubprogram(name: "nope", scope: !3, file: !3, line: 1, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
!5 = !DISubroutineType(types: !6)
!6 = !{!7}
!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!8 = !{!9}
!9 = !DILocalVariable(name: "toast", scope: !4, file: !3, line: 1, type: !7)
!10 = !DILocation(line: 1, scope: !4)
...
---
name: foo
tracksRegLiveness: true
frameInfo:
stackSize: 8
offsetAdjustment: -8
adjustsStack: true
hasCalls: true
cvBytesOfCalleeSavedRegisters: 8
fixedStack:
- { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default,
callee-saved-register: '$rbx', callee-saved-restored: true, debug-info-variable: '',
debug-info-expression: '', debug-info-location: '' }
stack: []
body: |
bb.0.entry:
successors: %bb.1(0x80000000)
liveins: $rbx
frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp, debug-location !10
CFI_INSTRUCTION def_cfa_offset 16
CFI_INSTRUCTION offset $rbx, -16
CALL64pcrel32 @geti32, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !10
DBG_VALUE $eax, $noreg, !9, !DIExpression(), debug-location !10
$ebx = MOV32rr killed $eax, debug-location !10
JMP_1 %bb.1
bb.1.loop2:
successors: %bb.2
liveins: $ebx
MOV32mr $rip, 1, $noreg, @glob, $noreg, renamable $ebx :: (store 4 into @glob)
bb.2.loop:
successors: %bb.1, %bb.3
liveins: $ebx
$edi = MOV32rr $ebx
CALL64pcrel32 @escape, csr_64, implicit $rsp, implicit $ssp, implicit killed $edi, implicit-def $rsp, implicit-def $ssp
CALL64pcrel32 @booler, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $al, debug-location !10
TEST8ri killed renamable $al, 1, implicit-def $eflags
JCC_1 %bb.1, 5, implicit $eflags
bb.3.exit:
liveins: $ebx
$eax = MOV32rr killed $ebx
$rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 8
RETQ $eax
...