1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
# RUN: llc %s -o - -mtriple=x86_64-unknown-unknown \
# RUN: -experimental-debug-variable-locations -run-pass=livedebugvalues \
# RUN: | FileCheck %s --check-prefix=CHECK
#
# Copy of dbg-phis-merging-in-ldv.mir, where I've added a loop in between the
# DBG_PHI "definitions" of values, and the DBG_INSTR_REFs where they're used.
# We should be able to traverse this obstacle.
--- |
; ModuleID = 'before.mir'
source_filename = "test.c"
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 = "x86_64-unknown-linux-gnu"
define dso_local i32 @foo(i64 %bar, i64 %baz) !dbg !7 {
entry:
call void @llvm.dbg.value(metadata i64 %bar, metadata !12, metadata !DIExpression()), !dbg !13
call void @llvm.dbg.value(metadata i64 %baz, metadata !14, metadata !DIExpression()), !dbg !13
call void @ext(i64 %bar), !dbg !15
%add = add nsw i64 %bar, 12, !dbg !16
call void @llvm.dbg.value(metadata i64 %add, metadata !12, metadata !DIExpression()), !dbg !13
call void @ext(i64 %add), !dbg !17
%add1 = add nsw i64 %baz, 1, !dbg !18
call void @llvm.dbg.value(metadata i64 %add1, metadata !14, metadata !DIExpression()), !dbg !13
%call = call i64 @getlong(), !dbg !19
%tobool = icmp ne i64 %call, 0, !dbg !19
br i1 %tobool, label %if.then, label %if.else, !dbg !21
if.then: ; preds = %entry
%add2 = add nsw i64 %add, 1, !dbg !22
call void @llvm.dbg.value(metadata i64 %add2, metadata !12, metadata !DIExpression()), !dbg !13
br label %if.end, !dbg !24
if.else: ; preds = %entry
%add3 = add nsw i64 %add, 2, !dbg !25
call void @llvm.dbg.value(metadata i64 %add3, metadata !12, metadata !DIExpression()), !dbg !13
br label %if.end
if.end: ; preds = %if.else, %if.then
%bar.addr.0 = phi i64 [ %add2, %if.then ], [ %add3, %if.else ], !dbg !27
call void @llvm.dbg.value(metadata i64 %bar.addr.0, metadata !12, metadata !DIExpression()), !dbg !13
%add4 = add nsw i64 %bar.addr.0, %add1, !dbg !28
call void @llvm.dbg.value(metadata i64 %add4, metadata !12, metadata !DIExpression()), !dbg !13
call void @ext(i64 %add4), !dbg !29
%conv = trunc i64 %add4 to i32, !dbg !30
ret i32 %conv, !dbg !31
}
; Function Attrs: nounwind readnone speculatable willreturn
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
declare dso_local void @ext(i64)
declare dso_local i64 @getlong()
; Function Attrs: nounwind readnone speculatable willreturn
declare void @llvm.dbg.value(metadata, metadata, metadata) #0
attributes #0 = { nounwind readnone speculatable willreturn }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "test.c", directory: ".")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang"}
!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!8 = !DISubroutineType(types: !9)
!9 = !{!10, !11, !11}
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!11 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed)
!12 = !DILocalVariable(name: "bar", arg: 1, scope: !7, file: !1, line: 3, type: !11)
!13 = !DILocation(line: 0, scope: !7)
!14 = !DILocalVariable(name: "baz", arg: 2, scope: !7, file: !1, line: 3, type: !11)
!15 = !DILocation(line: 4, column: 3, scope: !7)
!16 = !DILocation(line: 5, column: 7, scope: !7)
!17 = !DILocation(line: 6, column: 3, scope: !7)
!18 = !DILocation(line: 7, column: 7, scope: !7)
!19 = !DILocation(line: 9, column: 7, scope: !20)
!20 = distinct !DILexicalBlock(scope: !7, file: !1, line: 9, column: 7)
!21 = !DILocation(line: 9, column: 7, scope: !7)
!22 = !DILocation(line: 10, column: 9, scope: !23)
!23 = distinct !DILexicalBlock(scope: !20, file: !1, line: 9, column: 18)
!24 = !DILocation(line: 11, column: 3, scope: !23)
!25 = !DILocation(line: 12, column: 9, scope: !26)
!26 = distinct !DILexicalBlock(scope: !20, file: !1, line: 11, column: 10)
!27 = !DILocation(line: 0, scope: !20)
!28 = !DILocation(line: 15, column: 7, scope: !7)
!29 = !DILocation(line: 16, column: 3, scope: !7)
!30 = !DILocation(line: 17, column: 10, scope: !7)
!31 = !DILocation(line: 17, column: 3, scope: !7)
...
---
name: foo
alignment: 16
tracksRegLiveness: true
liveins:
- { reg: '$rdi' }
- { reg: '$rsi' }
frameInfo:
stackSize: 24
offsetAdjustment: -24
maxAlignment: 1
adjustsStack: true
hasCalls: true
maxCallFrameSize: 0
cvBytesOfCalleeSavedRegisters: 16
fixedStack:
- { id: 0, type: spill-slot, offset: -24, size: 8, alignment: 8, callee-saved-register: '$rbx' }
- { id: 1, type: spill-slot, offset: -16, size: 8, alignment: 16, callee-saved-register: '$r14' }
machineFunctionInfo: {}
body: |
bb.0.entry:
successors: %bb.2, %bb.1
liveins: $rdi, $rsi, $r14, $rbx
frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 16
frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 24
frame-setup PUSH64r undef $rax, implicit-def $rsp, implicit $rsp
CFI_INSTRUCTION def_cfa_offset 32
CFI_INSTRUCTION offset $rbx, -24
CFI_INSTRUCTION offset $r14, -16
$r14 = MOV64rr $rsi
$rbx = MOV64rr $rdi
CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, debug-location !15
renamable $rbx = ADD64ri32 killed renamable $rbx, 12, implicit-def $eflags, debug-location !16
$rdi = MOV64rr $rbx, debug-location !17
CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, debug-location !17
renamable $r14 = ADD64ri32 killed renamable $r14, 1, implicit-def $eflags, debug-location !18
CALL64pcrel32 @getlong, csr_64, implicit $rsp, implicit $ssp, implicit-def $rax, debug-location !19
CMP64ri8 killed renamable $rax, 0, implicit-def $eflags, debug-location !19
JCC_1 %bb.1, 5, implicit $eflags, debug-location !21
bb.2.if.else:
liveins: $rbx, $r14, $rax
renamable $rbx = ADD64ri32 killed renamable $rbx, 2, implicit-def $eflags, debug-location !25
DBG_PHI $r14, 1
DBG_PHI $rbx, 2
DBG_PHI $rax, 3
$rax = MOV64ri 0
JMP_1 %bb.3
bb.1.if.then:
liveins: $rbx, $r14, $rax
renamable $rbx = ADD64ri32 killed renamable $rbx, 1, implicit-def $eflags, debug-location !22
DBG_PHI $r14, 1
DBG_PHI $rbx, 2
DBG_PHI $rax, 3
bb.3:
$r15 = MOV64ri 0
CMP64ri8 $r15, 0, implicit-def $eflags, debug-location !19
JCC_1 %bb.3, 5, implicit $eflags, debug-location !21
bb.4:
liveins: $rbx, $r14
DBG_INSTR_REF 1, 0, !14, !DIExpression(), debug-location !13
DBG_INSTR_REF 2, 0, !12, !DIExpression(), debug-location !13
DBG_INSTR_REF 3, 0, !12, !DIExpression(), debug-location !13
; Value number 1 is live-through the above control flow from the two
; DBG_PHIs:
; CHECK: DBG_INSTR_REF 1, 0
; CHECK-NEXT: DBG_VALUE $r14
;
; While value number 2 has different defs that merge on entry to bb.3.
; These are both in $rbx though, and we should find its location:
; CHECK: DBG_INSTR_REF 2, 0
; CHECK-NEXT: DBG_VALUE $rbx
;
; Value number 3 cannot be resolved because $rax is clobbered in bb.2,
; meaning the merged value in bb.3 is incorrect. It should produce a
; DBG_VALUE $noreg.
; CHECK: DBG_INSTR_REF 3, 0
; CHECK-NEXT: DBG_VALUE $noreg
renamable $rbx = ADD64rr killed renamable $rbx, killed renamable $r14, implicit-def $eflags, debug-location !28
DBG_INSTR_REF 2, 0, !12, !DIExpression(), debug-location !13
; After clobbering rbx, the variable location should not be available.
; CHECK: DBG_INSTR_REF 2, 0
; CHECK-NEXT: DBG_VALUE $noreg
$rdi = MOV64rr $rbx, debug-location !29
CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, debug-location !29
$eax = MOV32rr $ebx, implicit killed $rbx, debug-location !31
$rsp = frame-destroy ADD64ri8 $rsp, 8, implicit-def dead $eflags, debug-location !31
CFI_INSTRUCTION def_cfa_offset 24, debug-location !31
$rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !31
CFI_INSTRUCTION def_cfa_offset 16, debug-location !31
$r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !31
CFI_INSTRUCTION def_cfa_offset 8, debug-location !31
RET64 implicit $eax, debug-location !31
...
|