xref: /llvm-project/llvm/test/DebugInfo/simplify-cfg-preserve-dbg-values.ll (revision b25ad38307fdf162d7030a002b6ef1d2048fda55)
1; RUN: opt %s -passes=simplifycfg,verify -S -o - | FileCheck %s
2;
3; Verify that SimplifyCFG does not invalidate operands for
4; llvm.dbg.value intrinsics.
5;
6; Reduced from the following example, compiled with
7; -O1 -g -fno-exceptions -fno-discard-value-names:
8;
9; void test() {
10;   bool a = false;
11;   bool b = false;
12;   bool c = false;
13;   [&a, &b, &c] { b = true; }();
14;
15;   if (a || b || c) {
16;     __builtin_debugtrap();
17;   }
18; }
19
20; CHECK: _Z4testv
21; CHECK-NOT: llvm.dbg.value(metadata !
22; CHECK: ret void
23
24%class.anon = type { ptr, ptr, ptr }
25
26; Function Attrs: nounwind uwtable
27define dso_local void @_Z4testv() local_unnamed_addr !dbg !7 {
28entry:
29  %a = alloca i8, align 1
30  %b = alloca i8, align 1
31  %c = alloca i8, align 1
32  %ref.tmp = alloca %class.anon, align 8
33  call void @llvm.dbg.value(metadata ptr %a, metadata !12, metadata !DIExpression(DW_OP_deref)), !dbg !16
34  call void @llvm.dbg.value(metadata i8 0, metadata !12, metadata !DIExpression()), !dbg !16
35  store i8 0, ptr %a, align 1, !dbg !16
36  call void @llvm.dbg.value(metadata ptr %b, metadata !14, metadata !DIExpression(DW_OP_deref)), !dbg !16
37  call void @llvm.dbg.value(metadata i8 0, metadata !14, metadata !DIExpression()), !dbg !16
38  store i8 0, ptr %b, align 1, !dbg !16
39  call void @llvm.dbg.value(metadata ptr %c, metadata !15, metadata !DIExpression(DW_OP_deref)), !dbg !16
40  call void @llvm.dbg.value(metadata i8 0, metadata !15, metadata !DIExpression()), !dbg !16
41  store i8 0, ptr %c, align 1, !dbg !16
42  store ptr %a, ptr %ref.tmp, align 8, !dbg !16
43  %0 = getelementptr inbounds %class.anon, ptr %ref.tmp, i64 0, i32 1, !dbg !16
44  store ptr %b, ptr %0, align 8, !dbg !16
45  %1 = getelementptr inbounds %class.anon, ptr %ref.tmp, i64 0, i32 2, !dbg !16
46  store ptr %c, ptr %1, align 8, !dbg !16
47  call fastcc void @"_ZZ4testvENK3$_0clEv"(ptr nonnull %ref.tmp), !dbg !16
48  %2 = load i8, ptr %a, align 1, !dbg !17
49  call void @llvm.dbg.value(metadata i8 %2, metadata !12, metadata !DIExpression()), !dbg !16
50  %tobool = icmp eq i8 %2, 0, !dbg !17
51  br i1 %tobool, label %lor.lhs.false, label %if.then, !dbg !17
52
53lor.lhs.false:                                    ; preds = %entry
54  %3 = load i8, ptr %b, align 1, !dbg !17
55  call void @llvm.dbg.value(metadata i8 %3, metadata !14, metadata !DIExpression()), !dbg !16
56  %tobool1 = icmp eq i8 %3, 0, !dbg !17
57  br i1 %tobool1, label %lor.lhs.false2, label %if.then, !dbg !17
58
59lor.lhs.false2:                                   ; preds = %lor.lhs.false
60  %4 = load i8, ptr %c, align 1, !dbg !17
61  call void @llvm.dbg.value(metadata i8 %4, metadata !15, metadata !DIExpression()), !dbg !16
62  %tobool3 = icmp eq i8 %4, 0, !dbg !17
63  br i1 %tobool3, label %if.end, label %if.then, !dbg !16
64
65if.then:                                          ; preds = %lor.lhs.false2, %lor.lhs.false, %entry
66  call void @llvm.debugtrap(), !dbg !19
67  br label %if.end, !dbg !19
68
69if.end:                                           ; preds = %lor.lhs.false2, %if.then
70  call void @llvm.dbg.value(metadata ptr %c, metadata !15, metadata !DIExpression(DW_OP_deref)), !dbg !16
71  call void @llvm.dbg.value(metadata ptr %b, metadata !14, metadata !DIExpression(DW_OP_deref)), !dbg !16
72  call void @llvm.dbg.value(metadata ptr %a, metadata !12, metadata !DIExpression(DW_OP_deref)), !dbg !16
73  ret void, !dbg !16
74}
75
76; Function Attrs: inlinehint nounwind uwtable
77define internal fastcc void @"_ZZ4testvENK3$_0clEv"(ptr %this) unnamed_addr align 2 !dbg !21 {
78entry:
79  call void @llvm.dbg.value(metadata ptr %this, metadata !34, metadata !DIExpression()), !dbg !36
80  %0 = getelementptr inbounds %class.anon, ptr %this, i32 0, i32 1, !dbg !36
81  %1 = load ptr, ptr %0, align 8, !dbg !36
82  store i8 1, ptr %1, align 1, !dbg !36
83  ret void, !dbg !36
84}
85
86; Function Attrs: nounwind
87declare void @llvm.debugtrap()
88
89; Function Attrs: nounwind readnone speculatable
90declare void @llvm.dbg.value(metadata, metadata, metadata)
91
92!llvm.dbg.cu = !{!0}
93!llvm.module.flags = !{!3, !4, !5}
94!llvm.ident = !{!6}
95
96!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 8.0.1-4 (tags/RELEASE_801/final)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
97!1 = !DIFile(filename: "test.cc", directory: "/dir")
98!2 = !{}
99!3 = !{i32 2, !"Dwarf Version", i32 4}
100!4 = !{i32 2, !"Debug Info Version", i32 3}
101!5 = !{i32 1, !"wchar_size", i32 4}
102!6 = !{!"clang version 8.0.1-4 (tags/RELEASE_801/final)"}
103!7 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", scope: !8, file: !8, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
104!8 = !DIFile(filename: "test.cc", directory: "/dir")
105!9 = !DISubroutineType(types: !10)
106!10 = !{null}
107!11 = !{!12, !14, !15}
108!12 = !DILocalVariable(name: "a", scope: !7, file: !8, line: 2, type: !13)
109!13 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean)
110!14 = !DILocalVariable(name: "b", scope: !7, file: !8, line: 3, type: !13)
111!15 = !DILocalVariable(name: "c", scope: !7, file: !8, line: 4, type: !13)
112!16 = !DILocation(line: 2, scope: !7)
113!17 = !DILocation(line: 7, scope: !18)
114!18 = distinct !DILexicalBlock(scope: !7, file: !8, line: 7)
115!19 = !DILocation(line: 8, scope: !20)
116!20 = distinct !DILexicalBlock(scope: !18, file: !8, line: 7)
117!21 = distinct !DISubprogram(name: "operator()", linkageName: "_ZZ4testvENK3$_0clEv", scope: !22, file: !8, line: 5, type: !28, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !32, retainedNodes: !33)
118!22 = distinct !DICompositeType(tag: DW_TAG_class_type, scope: !7, file: !8, line: 5, size: 192, flags: DIFlagTypePassByValue, elements: !23)
119!23 = !{!24, !26, !27}
120!24 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !22, file: !8, line: 5, baseType: !25, size: 64)
121!25 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !13, size: 64)
122!26 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !22, file: !8, line: 5, baseType: !25, size: 64, offset: 64)
123!27 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !22, file: !8, line: 5, baseType: !25, size: 64, offset: 128)
124!28 = !DISubroutineType(types: !29)
125!29 = !{null, !30}
126!30 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !31, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
127!31 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !22)
128!32 = !DISubprogram(name: "operator()", scope: !22, file: !8, line: 5, type: !28, scopeLine: 5, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
129!33 = !{!34}
130!34 = !DILocalVariable(name: "this", arg: 1, scope: !21, type: !35, flags: DIFlagArtificial | DIFlagObjectPointer)
131!35 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !31, size: 64)
132!36 = !DILocation(line: 0, scope: !21)
133