llvm-project/llvm/test/CodeGen/X86/tail-dup-debugvalue.mir
Stephen Tozer 98a021fcbf [DebugInfo] Attempt to preserve more information during tail duplication
Prior to this patch, tail duplication handled debug info poorly -
specifically, debug instructions would be dropped instead of being set
undef, potentially extending the lifetimes of prior debug values that
should be killed. The pass was also very aggressive with dropping debug
info, dropping debug info even when the SSA value it referred to was
still present. This patch attempts to handle debug info more carefully,
checking to see whether each affected debug value can still be live,
setting it undef if not.

Reviewed By: jmorse

Differential Revision: https://reviews.llvm.org/D106875
2021-12-03 15:30:05 +00:00

136 lines
5.4 KiB
YAML

# RUN: llc -run-pass=early-tailduplication -mtriple=x86_64-unknown-linux-gnu %s -o - | FileCheck %s
# Tail Duplication may update SSA values and invalidate any DBG_VALUEs that
# use those values; those DBG_VALUEs should be set undef. This is tested
# for DBG_VALUE users, and DBG_VALUE_LISTs that use the value multiple times.
# CHECK: ![[VAR_J:[0-9]+]] = !DILocalVariable(name: "j"
# CHECK: ![[VAR_K:[0-9]+]] = !DILocalVariable(name: "k"
# CHECK-LABEL: bb.1.L:
# CHECK: %[[REGISTER:[0-9]+]]:gr32 = PHI
# CHECK-LABEL: bb.2.if.end4:
# CHECK: DBG_VALUE_LIST ![[VAR_J]],
# CHECK-SAME: %[[REGISTER]], 1, %[[REGISTER]]
# CHECK: DBG_VALUE %[[REGISTER]], $noreg, ![[VAR_K]]
--- |
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 void @main() local_unnamed_addr #0 !dbg !15 {
entry:
br label %L.outer
L: ; preds = %L, %L.outer
%tobool2.not = icmp eq i32 undef, 0
br i1 %tobool2.not, label %if.end4, label %L
if.end4: ; preds = %L
call void @llvm.dbg.value(metadata !DIArgList(i32 %f.0.ph, i32 1, i32 %f.0.ph), metadata !19, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_LLVM_arg, 2, DW_OP_and, DW_OP_or, DW_OP_stack_value)), !dbg !21
%cmp = icmp slt i32 %f.0.ph, undef
br i1 %cmp, label %if.then5, label %if.end6
if.then5: ; preds = %if.end4
call void @h() #2
br label %L.outer
L.outer: ; preds = %if.then5, %entry
%f.0.ph = phi i32 [ 0, %if.then5 ], [ 1, %entry ]
br label %L
if.end6: ; preds = %if.end4
ret void
}
declare dso_local void @h() local_unnamed_addr
declare void @llvm.dbg.value(metadata, metadata, metadata)
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!13, !14}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "tail-dup-debugvalue.c", directory: "/tmp")
!2 = !{}
!3 = !{!4, !7, !9, !11}
!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression())
!5 = distinct !DIGlobalVariable(name: "a", scope: !0, file: !1, line: 2, type: !6, isLocal: false, isDefinition: true)
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression())
!8 = distinct !DIGlobalVariable(name: "b", scope: !0, file: !1, line: 2, type: !6, isLocal: false, isDefinition: true)
!9 = !DIGlobalVariableExpression(var: !10, expr: !DIExpression())
!10 = distinct !DIGlobalVariable(name: "c", scope: !0, file: !1, line: 2, type: !6, isLocal: false, isDefinition: true)
!11 = !DIGlobalVariableExpression(var: !12, expr: !DIExpression())
!12 = distinct !DIGlobalVariable(name: "d", scope: !0, file: !1, line: 2, type: !6, isLocal: false, isDefinition: true)
!13 = !{i32 2, !"Debug Info Version", i32 3}
!14 = !{i32 7, !"uwtable", i32 1}
!15 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 3, type: !16, scopeLine: 3, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !18)
!16 = !DISubroutineType(types: !17)
!17 = !{!6}
!18 = !{!19, !20}
!19 = !DILocalVariable(name: "j", scope: !15, file: !1, line: 14, type: !6)
!20 = !DILocalVariable(name: "k", scope: !15, file: !1, line: 14, type: !6)
!21 = !DILocation(line: 0, scope: !15)
...
---
name: main
alignment: 16
tracksRegLiveness: true
registers:
- { id: 0, class: gr32 }
- { id: 1, class: gr32 }
- { id: 2, class: gr32 }
- { id: 3, class: gr8 }
- { id: 4, class: gr32 }
- { id: 5, class: gr32 }
- { id: 6, class: gr32 }
frameInfo:
maxAlignment: 1
hasCalls: true
machineFunctionInfo: {}
body: |
bb.0.entry:
successors: %bb.4(0x80000000)
%1:gr32 = MOV32ri 1
JMP_1 %bb.4
bb.1.L:
successors: %bb.2(0x04000000), %bb.1(0x7c000000)
%2:gr32 = MOV32r0 implicit-def dead $eflags
%3:gr8 = COPY %2.sub_8bit
TEST8rr %3, %3, implicit-def $eflags
JCC_1 %bb.1, 5, implicit $eflags
JMP_1 %bb.2
bb.2.if.end4:
successors: %bb.3(0x783e0f0f), %bb.5(0x07c1f0f1)
DBG_VALUE_LIST !19, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_LLVM_arg, 2, DW_OP_and, DW_OP_or, DW_OP_stack_value), %0, 1, %0, debug-location !21
DBG_VALUE %0, $noreg, !20, !DIExpression(), debug-location !21
%5:gr32 = IMPLICIT_DEF
%4:gr32 = SUB32rr %0, killed %5, implicit-def $eflags
JCC_1 %bb.5, 13, implicit $eflags
JMP_1 %bb.3
bb.3.if.then5:
successors: %bb.4(0x80000000)
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
CALL64pcrel32 @h, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp
ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
%6:gr32 = MOV32r0 implicit-def dead $eflags
bb.4.L.outer:
successors: %bb.1(0x80000000)
%0:gr32 = PHI %1, %bb.0, %6, %bb.3
JMP_1 %bb.1
bb.5.if.end6:
RET 0
...