xref: /llvm-project/llvm/test/Transforms/LCSSA/rewrite-existing-dbg-values.ll (revision 094572701dce4aaf36f4521d6cf750420d39f206)
1; RUN: opt -S -passes=lcssa < %s | FileCheck %s
2; RUN: opt -S -passes=lcssa < %s --try-experimental-debuginfo-iterators | FileCheck %s
3
4; Reproducer for PR39019.
5;
6; Verify that the llvm.dbg.values are updated to use the PHI nodes inserted by
7; LCSSA.
8
9; For the test case @single_exit, we can rewrite all llvm.dbg.value calls
10; to use the inserted PHI.
11
12; CHECK-LABEL: @single_exit(
13
14; CHECK-LABEL: inner.body:
15; CHECK: %add = add nsw i32 0, 2
16; CHECK: #dbg_value(i32 %add, [[VAR:![0-9]+]], !DIExpression(),
17
18
19; CHECK-LABEL: outer.exit:
20; CHECK-NEXT: [[PN:%[^ ]*]] = phi i32 [ %add.lcssa, %outer.latch ]
21; CHECK-NEXT: #dbg_value(i32 [[PN]], [[VAR]], !DIExpression(),
22; CHECK-NEXT: call void @bar(i32 [[PN]])
23
24; CHECK-LABEL: exit:
25; CHECK-NEXT: #dbg_value(i32 [[PN]], [[VAR]], !DIExpression(),
26
27define void @single_exit()  !dbg !6 {
28entry:
29  br label %outer.header, !dbg !12
30
31outer.header:                                     ; preds = %outer.latch, %entry
32  br label %inner.body, !dbg !12
33
34inner.body:                                       ; preds = %inner.body, %outer.header
35  %add = add nsw i32 0, 2, !dbg !12
36  call void @llvm.dbg.value(metadata i32 %add, metadata !9, metadata !DIExpression()), !dbg !12
37  br i1 false, label %inner.body, label %inner.exit, !dbg !12
38
39inner.exit:                                       ; preds = %inner.body
40  br label %outer.latch
41
42outer.latch:                                      ; preds = %inner.exit
43  br i1 false, label %outer.header, label %outer.exit, !dbg !12
44
45outer.exit:                                       ; preds = %outer.latch
46  call void @llvm.dbg.value(metadata i32 %add, metadata !9, metadata !DIExpression()), !dbg !12
47  tail call void @bar(i32 %add), !dbg !12
48  br label %exit
49
50exit:                                             ; preds = %outer.exit
51  call void @llvm.dbg.value(metadata i32 %add, metadata !9, metadata !DIExpression()), !dbg !12
52  ret void, !dbg !12
53}
54
55; For the test case @multi_exit, we cannot update the llvm.dbg.value call in exit,
56; because LCSSA did not insert a PHI node in %exit, as there is no non-debug
57; use.
58
59; CHECK-LABEL: @multi_exit()
60
61; CHECK-LABEL: for.header:
62; CHECK-NEXT: %add = add nsw i32 0, 2
63; CHECK-NEXT: #dbg_value(i32 %add, [[VAR2:![0-9]+]], !DIExpression(),
64
65; CHECK-LABEL: for.exit1:
66; CHECK-NEXT: [[PN1:%[^ ]*]] = phi i32 [ %add, %for.header ]
67; CHECK-NEXT: br label %for.exit1.succ
68
69; CHECK-LABEL: for.exit1.succ:
70; CHECK-NEXT: #dbg_value(i32 [[PN1]], [[VAR2]], !DIExpression(),
71; CHECK-NEXT: call void @bar(i32 [[PN1]])
72
73; CHECK-LABEL: for.exit2:
74; CHECK-NEXT: [[PN2:%[^ ]*]] = phi i32 [ %add, %for.latch ]
75; CHECK-NEXT: #dbg_value(i32 [[PN2]], [[VAR2]], !DIExpression(),
76; CHECK-NEXT: call void @bar(i32 [[PN2]])
77
78; CHECK-LABEL: exit:
79; CHECK-NEXT: #dbg_value(i32 %add, [[VAR2]], !DIExpression(),
80
81define void @multi_exit()  !dbg !13 {
82entry:
83  br label %for.header, !dbg !14
84
85for.header:                                       ; preds = %for.latch, %entry
86  %add = add nsw i32 0, 2, !dbg !14
87  call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !14
88  br i1 false, label %for.latch, label %for.exit1, !dbg !14
89
90for.latch:                                        ; preds = %for.header
91  br i1 false, label %for.header, label %for.exit2, !dbg !14
92
93for.exit1:                                        ; preds = %for.header
94  br label %for.exit1.succ
95
96for.exit1.succ:                                   ; preds = %for.exit1
97  call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !14
98  tail call void @bar(i32 %add), !dbg !14
99  br label %exit
100
101for.exit2:                                        ; preds = %for.latch
102  call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !14
103  tail call void @bar(i32 %add), !dbg !14
104  br label %exit
105
106exit:                                             ; preds = %for.exit2, %for.exit1.succ
107  call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !14
108  ret void, !dbg !14
109}
110
111; CHECK: [[VAR]] = !DILocalVariable(name: "sum",
112; CHECK: [[VAR2]] = !DILocalVariable(name: "sum2",
113
114declare void @bar(i32)
115
116declare void @llvm.dbg.value(metadata, metadata, metadata)
117
118!llvm.dbg.cu = !{!0}
119!llvm.module.flags = !{!3, !4}
120!llvm.ident = !{!5}
121
122!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2, nameTableKind: None)
123!1 = !DIFile(filename: "foo.c", directory: "/")
124!2 = !{}
125!3 = !{i32 2, !"Dwarf Version", i32 4}
126!4 = !{i32 2, !"Debug Info Version", i32 3}
127!5 = !{!"clang version 8.0.0"}
128!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 10, type: !7, scopeLine: 10, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
129!7 = !DISubroutineType(types: !2)
130!8 = !{!9}
131!9 = !DILocalVariable(name: "sum", scope: !10, file: !1, line: 11, type: !11)
132!10 = !DILexicalBlockFile(scope: !6, file: !1, discriminator: 0)
133!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
134!12 = !DILocation(line: 0, scope: !10)
135!13 = distinct !DISubprogram(name: "multi_exit", scope: !1, file: !1, line: 10, type: !7, scopeLine: 10, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
136!14 = !DILocation(line: 0, scope: !15)
137!15 = !DILexicalBlockFile(scope: !13, file: !1, discriminator: 0)
138!16 = !DILocalVariable(name: "sum2", scope: !15, file: !1, line: 11, type: !11)
139