xref: /llvm-project/llvm/test/Transforms/SimpleLoopUnswitch/debuginfo.ll (revision 094572701dce4aaf36f4521d6cf750420d39f206)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s
3; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s --try-experimental-debuginfo-iterators | FileCheck %s
4;
5;; Check that when we duplicate the load in the loop header, we also duplicate
6;; the corresponding dbg.value.
7;; FIXME: the hoisted load dominates the duplicated dbg.value, however as it's
8;; not subsequently used in the loop, so it doesn't get remapped into the
9;; debug user and we get a undef/poison dbg.value. This is suboptimal, but it's
10;; important that the dbg.value gets duplicated nonetheless.
11
12declare void @clobber()
13declare void @llvm.dbg.value(metadata, metadata, metadata)
14
15define i32 @partial_unswitch_true_successor(ptr %ptr, i32 %N) {
16; CHECK-LABEL: @partial_unswitch_true_successor(
17; CHECK-NEXT:  entry:
18; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4
19; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100
20; CHECK-NEXT:    br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
21; CHECK:       entry.split.us:
22; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
23; CHECK:       loop.header.us:
24; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]
25; CHECK-NEXT:      #dbg_value(i32 poison, [[META3:![0-9]+]], !DIExpression(), [[META8:![0-9]+]])
26; CHECK-NEXT:    br label [[NOCLOBBER_US:%.*]]
27; CHECK:       noclobber.us:
28; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
29; CHECK:       loop.latch.us:
30; CHECK-NEXT:    [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]
31; CHECK-NEXT:    [[IV_NEXT_US]] = add i32 [[IV_US]], 1
32; CHECK-NEXT:    br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]
33; CHECK:       exit.split.us:
34; CHECK-NEXT:    br label [[EXIT:%.*]]
35; CHECK:       entry.split:
36; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
37; CHECK:       loop.header:
38; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
39; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR]], align 4
40; CHECK-NEXT:      #dbg_value(i32 [[LV]], [[META3]], !DIExpression(), [[META8]])
41; CHECK-NEXT:    [[SC:%.*]] = icmp eq i32 [[LV]], 100
42; CHECK-NEXT:    br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]
43; CHECK:       noclobber:
44; CHECK-NEXT:    br label [[LOOP_LATCH]]
45; CHECK:       clobber:
46; CHECK-NEXT:    call void @clobber()
47; CHECK-NEXT:    br label [[LOOP_LATCH]]
48; CHECK:       loop.latch:
49; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N]]
50; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
51; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP9:![0-9]+]]
52; CHECK:       exit.split:
53; CHECK-NEXT:    br label [[EXIT]]
54; CHECK:       exit:
55; CHECK-NEXT:    ret i32 10
56;
57entry:
58  br label %loop.header
59
60loop.header:
61  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
62  %lv = load i32, ptr %ptr
63  call void @llvm.dbg.value(metadata i32 %lv, metadata !6, metadata !DIExpression()), !dbg !7
64  %sc = icmp eq i32 %lv, 100
65  br i1 %sc, label %noclobber, label %clobber
66
67noclobber:
68  br label %loop.latch
69
70clobber:
71  call void @clobber()
72  br label %loop.latch
73
74loop.latch:
75  %c = icmp ult i32 %iv, %N
76  %iv.next = add i32 %iv, 1
77  br i1 %c, label %loop.header, label %exit
78
79exit:
80  ret i32 10
81}
82
83!llvm.module.flags = !{!21}
84!llvm.dbg.cu = !{!2}
85
86!0 = distinct !DISubprogram(name: "foo", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !2, file: !20, scope: !1, type: !3)
87!1 = !DIFile(filename: "b.c", directory: "/private/tmp")
88!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang", isOptimized: true, emissionKind: FullDebug, file: !20)
89!3 = !DISubroutineType(types: !4)
90!4 = !{!5}
91!5 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
92!6 = !DILocalVariable(name: "i", line: 2, arg: 1, scope: !0, file: !1, type: !5)
93!7 = !DILocation(line: 2, column: 13, scope: !0)
94!9 = !DILocalVariable(name: "k", line: 3, scope: !10, file: !1, type: !5)
95!10 = distinct !DILexicalBlock(line: 2, column: 16, file: !20, scope: !0)
96!11 = !DILocation(line: 3, column: 12, scope: !10)
97!12 = !DILocation(line: 4, column: 3, scope: !10)
98!13 = !DILocation(line: 5, column: 5, scope: !14)
99!14 = distinct !DILexicalBlock(line: 4, column: 10, file: !20, scope: !10)
100!15 = !DILocation(line: 6, column: 3, scope: !14)
101!16 = !DILocation(line: 7, column: 5, scope: !17)
102!17 = distinct !DILexicalBlock(line: 6, column: 10, file: !20, scope: !10)
103!18 = !DILocation(line: 8, column: 3, scope: !17)
104!19 = !DILocation(line: 9, column: 3, scope: !10)
105!20 = !DIFile(filename: "b.c", directory: "/private/tmp")
106!21 = !{i32 1, !"Debug Info Version", i32 3}
107
108
109