llvm-project/llvm/test/Transforms/SimplifyCFG/speculate-dbgvalue.ll
Jeremy Morse eaffcc85ea
[DebugInfo][RemoveDIs] Make dropping variable locations explicit (#72399)
In present-day debug-info, when you delete all instructions, you delete
all their debug-info with it because debug-info is stored in
instructions. With debug-info stored in DPValue objects however,
deleting instructions causes DPValue objects to clump together into a
large blob of debug-info that hangs around in the block, as nothing has
explicitly deleted it.

To restore this behaviour, scatter calls to dropDbgValues around in
places that used to delete chunks of dbg.values, for example during
stripDebugInfo and in the code that deletes everything after an
Unreachable instruction. DCE is another example.

The tests with --try... added to them are new scenarios where we can now
correctly replicate the "normal" debug-info behaviour. Alas, there's no
explicit test for the opt -strip-debug option though (in dbg.value mode
or DPValue mode).
2023-11-21 00:01:00 +00:00

85 lines
4.3 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 | FileCheck %s
; RUN: opt < %s -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 --try-experimental-debuginfo-iterators | FileCheck %s
; This test case was generated from speculate-dbgvalue.c:
;
; int test1(int getdirt, int dirt) {
; int result = 100;
; if (getdirt != 0)
; result = dirt;
; return result;
; }
;
; using
; clang speculate-dbgvalue.c -S -emit-llvm -g -O3 -mllvm -disable-llvm-optzns -o - | opt -passes=mem2reg -S
; Function Attrs: nounwind uwtable
define i32 @test1(i32 %getdirt, i32 %dirt) #0 !dbg !7 {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[GETDIRT:%.*]], metadata !12, metadata !DIExpression()), !dbg !15
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[DIRT:%.*]], metadata !13, metadata !DIExpression()), !dbg !16
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 100, metadata !14, metadata !DIExpression()), !dbg !17
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[GETDIRT]], 0, !dbg !18
; *** We used to get an incorrect "call void @llvm.dbg.value(metadata i32 [[DIRT]], metadata !14, metadata !DIExpression()), !dbg !17" here, before the select. ***
; CHECK-NOT: call void @llvm.dbg.value(metadata i32 [[DIRT]], metadata !14
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[CMP]], i32 [[DIRT]], i32 100, !dbg !20
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[RESULT]], metadata !14, metadata !DIExpression()), !dbg !17
; CHECK-NEXT: ret i32 [[RESULT]], !dbg !21
; CHECK: !12 = !DILocalVariable(name: "getdirt"
; CHECK: !13 = !DILocalVariable(name: "dirt"
; CHECK: !14 = !DILocalVariable(name: "result"
;
entry:
call void @llvm.dbg.value(metadata i32 %getdirt, metadata !12, metadata !DIExpression()), !dbg !15
call void @llvm.dbg.value(metadata i32 %dirt, metadata !13, metadata !DIExpression()), !dbg !16
call void @llvm.dbg.value(metadata i32 100, metadata !14, metadata !DIExpression()), !dbg !17
%cmp = icmp ne i32 %getdirt, 0, !dbg !18
br i1 %cmp, label %if.then, label %if.end, !dbg !20
if.then: ; preds = %entry
call void @llvm.dbg.value(metadata i32 %dirt, metadata !14, metadata !DIExpression()), !dbg !17
br label %if.end, !dbg !21
if.end: ; preds = %if.then, %entry
%result.0 = phi i32 [ %dirt, %if.then ], [ 100, %entry ]
call void @llvm.dbg.value(metadata i32 %result.0, metadata !14, metadata !DIExpression()), !dbg !17
ret i32 %result.0, !dbg !22
}
; Function Attrs: nounwind readnone speculatable
declare void @llvm.dbg.value(metadata, metadata, metadata) #1
attributes #0 = { nounwind uwtable }
attributes #1 = { nounwind readnone speculatable }
!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 6.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "speculate-dbgvalue.c", directory: "/foo")
!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 6.0.0"}
!7 = distinct !DISubprogram(name: "test1", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11)
!8 = !DISubroutineType(types: !9)
!9 = !{!10, !10, !10}
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!11 = !{!12, !13, !14}
!12 = !DILocalVariable(name: "getdirt", arg: 1, scope: !7, file: !1, line: 1, type: !10)
!13 = !DILocalVariable(name: "dirt", arg: 2, scope: !7, file: !1, line: 1, type: !10)
!14 = !DILocalVariable(name: "result", scope: !7, file: !1, line: 2, type: !10)
!15 = !DILocation(line: 1, column: 15, scope: !7)
!16 = !DILocation(line: 1, column: 28, scope: !7)
!17 = !DILocation(line: 2, column: 7, scope: !7)
!18 = !DILocation(line: 3, column: 15, scope: !19)
!19 = distinct !DILexicalBlock(scope: !7, file: !1, line: 3, column: 7)
!20 = !DILocation(line: 3, column: 7, scope: !7)
!21 = !DILocation(line: 4, column: 5, scope: !19)
!22 = !DILocation(line: 5, column: 3, scope: !7)