llvm.org GIT mirror llvm / f05b45f
Pass to emit DWARF path discriminators. DWARF discriminators are used to distinguish multiple control flow paths on the same source location. When this happens, instructions across basic block boundaries will share the same debug location. This pass detects this situation and creates a new lexical scope to one of the two instructions. This lexical scope is a child scope of the original and contains a new discriminator value. This discriminator is then picked up from MCObjectStreamer::EmitDwarfLocDirective to be written on the object file. This fixes http://llvm.org/bugs/show_bug.cgi?id=18270. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202752 91177308-0d34-0410-b5e6-96231b3b80d8 Diego Novillo 6 years ago
11 changed file(s) with 488 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
700700 StringRef getFilename() const { return getScope().getFilename(); }
701701 StringRef getDirectory() const { return getScope().getDirectory(); }
702702 bool Verify() const;
703 bool atSameLineAs(const DILocation &Other) const {
704 return (getLineNumber() == Other.getLineNumber() &&
705 getFilename() == Other.getFilename());
706 }
707 /// getDiscriminator - DWARF discriminators are used to distinguish
708 /// identical file locations for instructions that are on different
709 /// basic blocks. If two instructions are inside the same lexical block
710 /// and are in different basic blocks, we create a new lexical block
711 /// with identical location as the original but with a different
712 /// discriminator value (lib/Transforms/Util/AddDiscriminators.cpp
713 /// for details).
714 unsigned getDiscriminator() const {
715 // Since discriminators are associated with lexical blocks, make
716 // sure this location is a lexical block before retrieving its
717 // value.
718 return getScope().isLexicalBlock()
719 ? getFieldAs(2).getDiscriminator()
720 : 0;
721 }
722 unsigned computeNewDiscriminator(LLVMContext &Ctx);
723 DILocation copyWithNewScope(LLVMContext &Ctx, DILexicalBlock NewScope);
703724 };
704725
705726 class DIObjCProperty : public DIDescriptor {
6262 void initializeTarget(PassRegistry&);
6363
6464 void initializeAAEvalPass(PassRegistry&);
65 void initializeAddDiscriminatorsPass(PassRegistry&);
6566 void initializeADCEPass(PassRegistry&);
6667 void initializeAliasAnalysisAnalysisGroup(PassRegistry&);
6768 void initializeAliasAnalysisCounterPass(PassRegistry&);
375375 //
376376 FunctionPass *createScalarizerPass();
377377
378 //===----------------------------------------------------------------------===//
379 //
380 // AddDiscriminators - Add DWARF path discriminators to the IR.
381 FunctionPass *createAddDiscriminatorsPass();
382
378383 } // End llvm namespace
379384
380385 #endif
2121 #include "llvm/IR/Instructions.h"
2222 #include "llvm/IR/IntrinsicInst.h"
2323 #include "llvm/IR/Intrinsics.h"
24 #include "LLVMContextImpl.h"
2425 #include "llvm/IR/Module.h"
2526 #include "llvm/Support/Debug.h"
2627 #include "llvm/Support/Dwarf.h"
815816 return DIArray();
816817
817818 return DIArray(getNodeField(DbgNode, 11));
819 }
820
821 /// copyWithNewScope - Return a copy of this location, replacing the
822 /// current scope with the given one.
823 DILocation DILocation::copyWithNewScope(LLVMContext &Ctx,
824 DILexicalBlock NewScope) {
825 SmallVector Elts;
826 assert(Verify());
827 for (unsigned I = 0; I < DbgNode->getNumOperands(); ++I) {
828 if (I != 2)
829 Elts.push_back(DbgNode->getOperand(I));
830 else
831 Elts.push_back(NewScope);
832 }
833 MDNode *NewDIL = MDNode::get(Ctx, Elts);
834 return DILocation(NewDIL);
835 }
836
837 /// computeNewDiscriminator - Generate a new discriminator value for this
838 /// file and line location.
839 unsigned DILocation::computeNewDiscriminator(LLVMContext &Ctx) {
840 std::pair Key(getFilename().data(), getLineNumber());
841 return ++Ctx.pImpl->DiscriminatorTable[Key];
818842 }
819843
820844 /// fixupSubprogramName - Replace contains special characters used
351351 /// for an index. The ValueHandle ensures that ScopeINlinedAtIdx stays up
352352 /// to date.
353353 std::vector > ScopeInlinedAtRecords;
354
354
355 /// DiscriminatorTable - This table maps file:line locations to an
356 /// integer representing the next DWARF path discriminator to assign to
357 /// instructions in different blocks at the same location.
358 DenseMap, unsigned> DiscriminatorTable;
359
355360 /// IntrinsicIDCache - Cache of intrinsic name (string) to numeric ID mappings
356361 /// requested in this context
357362 typedef DenseMap IntrinsicIDCacheTy;
0 //===- AddDiscriminators.cpp - Insert DWARF path discriminators -----------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file adds DWARF discriminators to the IR. Path discriminators are
10 // used to decide what CFG path was taken inside sub-graphs whose instructions
11 // share the same line and column number information.
12 //
13 // The main user of this is the sample profiler. Instruction samples are
14 // mapped to line number information. Since a single line may be spread
15 // out over several basic blocks, discriminators add more precise location
16 // for the samples.
17 //
18 // For example,
19 //
20 // 1 #define ASSERT(P)
21 // 2 if (!(P))
22 // 3 abort()
23 // ...
24 // 100 while (true) {
25 // 101 ASSERT (sum < 0);
26 // 102 ...
27 // 130 }
28 //
29 // when converted to IR, this snippet looks something like:
30 //
31 // while.body: ; preds = %entry, %if.end
32 // %0 = load i32* %sum, align 4, !dbg !15
33 // %cmp = icmp slt i32 %0, 0, !dbg !15
34 // br i1 %cmp, label %if.end, label %if.then, !dbg !15
35 //
36 // if.then: ; preds = %while.body
37 // call void @abort(), !dbg !15
38 // br label %if.end, !dbg !15
39 //
40 // Notice that all the instructions in blocks 'while.body' and 'if.then'
41 // have exactly the same debug information. When this program is sampled
42 // at runtime, the profiler will assume that all these instructions are
43 // equally frequent. This, in turn, will consider the edge while.body->if.then
44 // to be frequently taken (which is incorrect).
45 //
46 // By adding a discriminator value to the instructions in block 'if.then',
47 // we can distinguish instructions at line 101 with discriminator 0 from
48 // the instructions at line 101 with discriminator 1.
49 //
50 // For more details about DWARF discriminators, please visit
51 // http://wiki.dwarfstd.org/index.php?title=Path_Discriminators
52 //===----------------------------------------------------------------------===//
53
54 #define DEBUG_TYPE "add-discriminators"
55
56 #include "llvm/Transforms/Scalar.h"
57 #include "llvm/DebugInfo.h"
58 #include "llvm/DIBuilder.h"
59 #include "llvm/IR/BasicBlock.h"
60 #include "llvm/IR/Instructions.h"
61 #include "llvm/IR/LLVMContext.h"
62 #include "llvm/IR/Constants.h"
63 #include "llvm/IR/Module.h"
64 #include "llvm/Pass.h"
65 #include "llvm/Support/CommandLine.h"
66 #include "llvm/Support/Debug.h"
67 #include "llvm/Support/raw_ostream.h"
68
69 using namespace llvm;
70
71 namespace {
72 struct AddDiscriminators : public FunctionPass {
73 static char ID; // Pass identification, replacement for typeid
74 AddDiscriminators() : FunctionPass(ID) {
75 initializeAddDiscriminatorsPass(*PassRegistry::getPassRegistry());
76 }
77
78 virtual bool runOnFunction(Function &F);
79 };
80 }
81
82 char AddDiscriminators::ID = 0;
83 INITIALIZE_PASS_BEGIN(AddDiscriminators, "add-discriminators",
84 "Add DWARF path discriminators", false, false)
85 INITIALIZE_PASS_END(AddDiscriminators, "add-discriminators",
86 "Add DWARF path discriminators", false, false)
87
88 // Command line option to disable discriminator generation even in the
89 // presence of debug information. This is only needed when debugging
90 // debug info generation issues.
91 static cl::opt
92 NoDiscriminators("no-discriminators", cl::init(false),
93 cl::desc("Disable generation of discriminator information."));
94
95 FunctionPass *llvm::createAddDiscriminatorsPass() {
96 return new AddDiscriminators();
97 }
98
99 static bool hasDebugInfo(const Function &F) {
100 NamedMDNode *CUNodes = F.getParent()->getNamedMetadata("llvm.dbg.cu");
101 return CUNodes != 0;
102 }
103
104 /// \brief Assign DWARF discriminators.
105 ///
106 /// To assign discriminators, we examine the boundaries of every
107 /// basic block and its successors. Suppose there is a basic block B1
108 /// with successor B2. The last instruction I1 in B1 and the first
109 /// instruction I2 in B2 are located at the same file and line number.
110 /// This situation is illustrated in the following code snippet:
111 ///
112 /// if (i < 10) x = i;
113 ///
114 /// entry:
115 /// br i1 %cmp, label %if.then, label %if.end, !dbg !10
116 /// if.then:
117 /// %1 = load i32* %i.addr, align 4, !dbg !10
118 /// store i32 %1, i32* %x, align 4, !dbg !10
119 /// br label %if.end, !dbg !10
120 /// if.end:
121 /// ret void, !dbg !12
122 ///
123 /// Notice how the branch instruction in block 'entry' and all the
124 /// instructions in block 'if.then' have the exact same debug location
125 /// information (!dbg !10).
126 ///
127 /// To distinguish instructions in block 'entry' from instructions in
128 /// block 'if.then', we generate a new lexical block for all the
129 /// instruction in block 'if.then' that share the same file and line
130 /// location with the last instruction of block 'entry'.
131 ///
132 /// This new lexical block will have the same location information as
133 /// the previous one, but with a new DWARF discriminator value.
134 ///
135 /// One of the main uses of this discriminator value is in runtime
136 /// sample profilers. It allows the profiler to distinguish instructions
137 /// at location !dbg !10 that execute on different basic blocks. This is
138 /// important because while the predicate 'if (x < 10)' may have been
139 /// executed millions of times, the assignment 'x = i' may have only
140 /// executed a handful of times (meaning that the entry->if.then edge is
141 /// seldom taken).
142 ///
143 /// If we did not have discriminator information, the profiler would
144 /// assign the same weight to both blocks 'entry' and 'if.then', which
145 /// in turn will make it conclude that the entry->if.then edge is very
146 /// hot.
147 ///
148 /// To decide where to create new discriminator values, this function
149 /// traverses the CFG and examines instruction at basic block boundaries.
150 /// If the last instruction I1 of a block B1 is at the same file and line
151 /// location as instruction I2 of successor B2, then it creates a new
152 /// lexical block for I2 and all the instruction in B2 that share the same
153 /// file and line location as I2. This new lexical block will have a
154 /// different discriminator number than I1.
155 bool AddDiscriminators::runOnFunction(Function &F) {
156 // No need to do anything if there is no debug info for this function.
157 // If the function has debug information, but the user has disabled
158 // discriminators, do nothing.
159 if (!hasDebugInfo(F) || NoDiscriminators) return false;
160
161 bool Changed = false;
162 Module *M = F.getParent();
163 LLVMContext &Ctx = M->getContext();
164 DIBuilder Builder(*M);
165
166 // Traverse all the blocks looking for instructions in different
167 // blocks that are at the same file:line location.
168 for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
169 BasicBlock *B = I;
170 TerminatorInst *Last = B->getTerminator();
171 DebugLoc LastLoc = Last->getDebugLoc();
172 if (LastLoc.isUnknown()) continue;
173 DILocation LastDIL(LastLoc.getAsMDNode(Ctx));
174
175 for (unsigned I = 0; I < Last->getNumSuccessors(); ++I) {
176 BasicBlock *Succ = Last->getSuccessor(I);
177 Instruction *First = Succ->getFirstNonPHIOrDbgOrLifetime();
178 DebugLoc FirstLoc = First->getDebugLoc();
179 if (FirstLoc.isUnknown()) continue;
180 DILocation FirstDIL(FirstLoc.getAsMDNode(Ctx));
181
182 // If the first instruction (First) of Succ is at the same file
183 // location as B's last instruction (Last), add a new
184 // discriminator for First's location and all the instructions
185 // in Succ that share the same location with First.
186 if (FirstDIL.atSameLineAs(LastDIL)) {
187 // Create a new lexical scope and compute a new discriminator
188 // number for it.
189 StringRef Filename = FirstDIL.getFilename();
190 unsigned LineNumber = FirstDIL.getLineNumber();
191 unsigned ColumnNumber = FirstDIL.getColumnNumber();
192 DIScope Scope = FirstDIL.getScope();
193 DIFile File = Builder.createFile(Filename, Scope.getDirectory());
194 unsigned Discriminator = FirstDIL.computeNewDiscriminator(Ctx);
195 DILexicalBlock NewScope = Builder.createLexicalBlock(
196 Scope, File, LineNumber, ColumnNumber, Discriminator);
197 DILocation NewDIL = FirstDIL.copyWithNewScope(Ctx, NewScope);
198 DebugLoc newDebugLoc = DebugLoc::getFromDILocation(NewDIL);
199
200 // Attach this new debug location to First and every
201 // instruction following First that shares the same location.
202 for (BasicBlock::iterator I1(*First), E1 = Succ->end(); I1 != E1;
203 ++I1) {
204 if (I1->getDebugLoc() != FirstLoc) break;
205 I1->setDebugLoc(newDebugLoc);
206 DEBUG(dbgs() << NewDIL.getFilename() << ":" << NewDIL.getLineNumber()
207 << ":" << NewDIL.getColumnNumber() << ":"
208 << NewDIL.getDiscriminator() << *I1 << "\n");
209 }
210 DEBUG(dbgs() << "\n");
211 Changed = true;
212 }
213 }
214 }
215 return Changed;
216 }
0 add_llvm_library(LLVMTransformUtils
1 AddDiscriminators.cpp
12 ASanStackFrameLayout.cpp
23 BasicBlockUtils.cpp
34 BreakCriticalEdges.cpp
2020 /// initializeTransformUtils - Initialize all passes in the TransformUtils
2121 /// library.
2222 void llvm::initializeTransformUtils(PassRegistry &Registry) {
23 initializeAddDiscriminatorsPass(Registry);
2324 initializeBreakCriticalEdgesPass(Registry);
2425 initializeInstNamerPass(Registry);
2526 initializeLCSSAPass(Registry);
0 ; RUN: opt < %s -add-discriminators -S | FileCheck %s
1
2 ; Basic DWARF discriminator test. All the instructions in block
3 ; 'if.then' should have a different discriminator value than
4 ; the conditional branch at the end of block 'entry'.
5 ;
6 ; Original code:
7 ;
8 ; void foo(int i) {
9 ; int x;
10 ; if (i < 10) x = i;
11 ; }
12
13 define void @foo(i32 %i) #0 {
14 entry:
15 %i.addr = alloca i32, align 4
16 %x = alloca i32, align 4
17 store i32 %i, i32* %i.addr, align 4
18 %0 = load i32* %i.addr, align 4, !dbg !10
19 %cmp = icmp slt i32 %0, 10, !dbg !10
20 br i1 %cmp, label %if.then, label %if.end, !dbg !10
21
22 if.then: ; preds = %entry
23 %1 = load i32* %i.addr, align 4, !dbg !10
24 ; CHECK: %1 = load i32* %i.addr, align 4, !dbg !12
25
26 store i32 %1, i32* %x, align 4, !dbg !10
27 ; CHECK: store i32 %1, i32* %x, align 4, !dbg !12
28
29 br label %if.end, !dbg !10
30 ; CHECK: br label %if.end, !dbg !12
31
32 if.end: ; preds = %if.then, %entry
33 ret void, !dbg !12
34 }
35
36 attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
37
38 !llvm.dbg.cu = !{!0}
39 !llvm.module.flags = !{!7, !8}
40 !llvm.ident = !{!9}
41
42 !0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [basic.c] [DW_LANG_C99]
43 !1 = metadata !{metadata !"basic.c", metadata !"."}
44 !2 = metadata !{}
45 !3 = metadata !{metadata !4}
46 !4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"foo", metadata !"foo", metadata !"", i32 1, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i32)* @foo, null, null, metadata !2, i32 1} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
47 !5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [basic.c]
48 !6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !2, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
49 !7 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
50 !8 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
51 !9 = metadata !{metadata !"clang version 3.5 "}
52 !10 = metadata !{i32 3, i32 0, metadata !11, null}
53 !11 = metadata !{i32 786443, metadata !1, metadata !4, i32 3, i32 0, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [basic.c]
54 !12 = metadata !{i32 4, i32 0, metadata !4, null}
55
56 ; CHECK: !12 = metadata !{i32 3, i32 0, metadata !13, null}
57 ; CHECK: !13 = metadata !{i32 786443, metadata !1, metadata !11, i32 3, i32 0, i32 1, i32 0} ; [ DW_TAG_lexical_block ] [./basic.c]
58 ; CHECK: !14 = metadata !{i32 4, i32 0, metadata !4, null}
0 ; RUN: opt < %s -add-discriminators -S | FileCheck %s
1
2 ; Test that the only instructions that receive a new discriminator in
3 ; the block 'if.then' are those that share the same line number as
4 ; the branch in 'entry'.
5 ;
6 ; Original code:
7 ;
8 ; void foo(int i) {
9 ; int x, y;
10 ; if (i < 10) { x = i;
11 ; y = -i;
12 ; }
13 ; }
14
15 define void @foo(i32 %i) #0 {
16 entry:
17 %i.addr = alloca i32, align 4
18 %x = alloca i32, align 4
19 %y = alloca i32, align 4
20 store i32 %i, i32* %i.addr, align 4
21 %0 = load i32* %i.addr, align 4, !dbg !10
22 %cmp = icmp slt i32 %0, 10, !dbg !10
23 br i1 %cmp, label %if.then, label %if.end, !dbg !10
24
25 if.then: ; preds = %entry
26 %1 = load i32* %i.addr, align 4, !dbg !12
27 store i32 %1, i32* %x, align 4, !dbg !12
28
29 %2 = load i32* %i.addr, align 4, !dbg !14
30 ; CHECK: %2 = load i32* %i.addr, align 4, !dbg !15
31
32 %sub = sub nsw i32 0, %2, !dbg !14
33 ; CHECK: %sub = sub nsw i32 0, %2, !dbg !15
34
35 store i32 %sub, i32* %y, align 4, !dbg !14
36 ; CHECK: store i32 %sub, i32* %y, align 4, !dbg !15
37
38 br label %if.end, !dbg !15
39 ; CHECK: br label %if.end, !dbg !16
40
41 if.end: ; preds = %if.then, %entry
42 ret void, !dbg !16
43 ; CHECK: ret void, !dbg !17
44 }
45
46 attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
47
48 !llvm.dbg.cu = !{!0}
49 !llvm.module.flags = !{!7, !8}
50 !llvm.ident = !{!9}
51
52 !0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5 (trunk 199750) (llvm/trunk 199751)", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [first-only.c] [DW_LANG_C99]
53 !1 = metadata !{metadata !"first-only.c", metadata !"."}
54 !2 = metadata !{i32 0}
55 !3 = metadata !{metadata !4}
56 !4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"foo", metadata !"foo", metadata !"", i32 1, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i32)* @foo, null, null, metadata !2, i32 1} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
57 !5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [first-only.c]
58 !6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !2, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
59 !7 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
60 !8 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
61 !9 = metadata !{metadata !"clang version 3.5 (trunk 199750) (llvm/trunk 199751)"}
62 !10 = metadata !{i32 3, i32 0, metadata !11, null}
63
64 !11 = metadata !{i32 786443, metadata !1, metadata !4, i32 3, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [first-only.c]
65 ; CHECK: !11 = metadata !{i32 786443, metadata !1, metadata !4, i32 3, i32 0, i32 0}
66
67 !12 = metadata !{i32 3, i32 0, metadata !13, null}
68
69 !13 = metadata !{i32 786443, metadata !1, metadata !11, i32 3, i32 0, i32 1} ; [ DW_TAG_lexical_block ] [first-only.c]
70 ; CHECK: !13 = metadata !{i32 786443, metadata !1, metadata !14, i32 3, i32 0, i32 1, i32 0} ; [ DW_TAG_lexical_block ] [./first-only.c]
71
72 !14 = metadata !{i32 4, i32 0, metadata !13, null}
73 ; CHECK: !14 = metadata !{i32 786443, metadata !1, metadata !11, i32 3, i32 0, i32 1}
74
75 !15 = metadata !{i32 5, i32 0, metadata !13, null}
76 ; CHECK: !15 = metadata !{i32 4, i32 0, metadata !14, null}
77
78 !16 = metadata !{i32 6, i32 0, metadata !4, null}
79 ; CHECK: !16 = metadata !{i32 5, i32 0, metadata !14, null}
80 ; CHECK: !17 = metadata !{i32 6, i32 0, metadata !4, null}
81
0 ; RUN: opt < %s -add-discriminators -S | FileCheck %s
1
2 ; Discriminator support for multiple CFG paths on the same line.
3 ;
4 ; void foo(int i) {
5 ; int x;
6 ; if (i < 10) x = i; else x = -i;
7 ; }
8 ;
9 ; The two stores inside the if-then-else line must have different discriminator
10 ; values.
11
12 define void @foo(i32 %i) #0 {
13 entry:
14 %i.addr = alloca i32, align 4
15 %x = alloca i32, align 4
16 store i32 %i, i32* %i.addr, align 4
17 %0 = load i32* %i.addr, align 4, !dbg !10
18 %cmp = icmp slt i32 %0, 10, !dbg !10
19 br i1 %cmp, label %if.then, label %if.else, !dbg !10
20
21 if.then: ; preds = %entry
22 %1 = load i32* %i.addr, align 4, !dbg !10
23 ; CHECK: %1 = load i32* %i.addr, align 4, !dbg !12
24
25 store i32 %1, i32* %x, align 4, !dbg !10
26 ; CHECK: store i32 %1, i32* %x, align 4, !dbg !12
27
28 br label %if.end, !dbg !10
29 ; CHECK: br label %if.end, !dbg !12
30
31 if.else: ; preds = %entry
32 %2 = load i32* %i.addr, align 4, !dbg !10
33 ; CHECK: %2 = load i32* %i.addr, align 4, !dbg !14
34
35 %sub = sub nsw i32 0, %2, !dbg !10
36 ; CHECK: %sub = sub nsw i32 0, %2, !dbg !14
37
38 store i32 %sub, i32* %x, align 4, !dbg !10
39 ; CHECK: store i32 %sub, i32* %x, align 4, !dbg !14
40
41 br label %if.end
42
43 if.end: ; preds = %if.else, %if.then
44 ret void, !dbg !12
45 }
46
47 attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
48
49 !llvm.dbg.cu = !{!0}
50 !llvm.module.flags = !{!7, !8}
51 !llvm.ident = !{!9}
52
53 !0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5 (trunk 199750) (llvm/trunk 199751)", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [multiple.c] [DW_LANG_C99]
54 !1 = metadata !{metadata !"multiple.c", metadata !"."}
55 !2 = metadata !{i32 0}
56 !3 = metadata !{metadata !4}
57 !4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"foo", metadata !"foo", metadata !"", i32 1, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i32)* @foo, null, null, metadata !2, i32 1} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
58 !5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [multiple.c]
59 !6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !2, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
60 !7 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
61 !8 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
62 !9 = metadata !{metadata !"clang version 3.5 (trunk 199750) (llvm/trunk 199751)"}
63 !10 = metadata !{i32 3, i32 0, metadata !11, null}
64 !11 = metadata !{i32 786443, metadata !1, metadata !4, i32 3, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [multiple.c]
65 !12 = metadata !{i32 4, i32 0, metadata !4, null}
66
67 ; CHECK: !12 = metadata !{i32 3, i32 0, metadata !13, null}
68 ; CHECK: !13 = metadata !{i32 786443, metadata !1, metadata !11, i32 3, i32 0, i32 1, i32 0} ; [ DW_TAG_lexical_block ] [./multiple.c]
69 ; CHECK: !14 = metadata !{i32 3, i32 0, metadata !15, null}
70 ; CHECK: !15 = metadata !{i32 786443, metadata !1, metadata !11, i32 3, i32 0, i32 2, i32 1} ; [ DW_TAG_lexical_block ] [./multiple.c]