
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).
85 lines
4.3 KiB
LLVM
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)
|