llvm.org GIT mirror llvm / dd47b68
Merging r324039: (test case modified to work around r323886 et al.) ------------------------------------------------------------------------ r324039 | matze | 2018-02-02 01:08:19 +0100 (Fri, 02 Feb 2018) | 33 lines SplitKit: Fix liveness recomputation in some remat cases. Example situation: ``` BB0: %0 = ... use %0 ; ... condjump BB1 jmp BB2 BB1: %0 = ... ; rematerialized def from above (from earlier split step) jmp BB2 BB2: ; ... use %0 ``` %0 will have a live interval with 3 value numbers (for the BB0, BB1 and BB2 parts). Now SplitKit tries and succeeds in rematerializing the value number in BB2 (This only works because it is a secondary split so SplitKit is can trace this back to a single original def). We need to recompute all live ranges affected by a value number that we rematerialize. The case that we missed before is that when the value that is rematerialized is at a join (Phi VNI) then we also have to recompute liveness for the predecessor VNIs. rdar://35699130 Differential Revision: https://reviews.llvm.org/D42667 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_60@324218 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 1 year, 11 months ago
3 changed file(s) with 293 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
490490 return VNI;
491491 }
492492
493 void SplitEditor::forceRecompute(unsigned RegIdx, const VNInfo *ParentVNI) {
494 assert(ParentVNI && "Mapping NULL value");
495 ValueForcePair &VFP = Values[std::make_pair(RegIdx, ParentVNI->id)];
493 void SplitEditor::forceRecompute(unsigned RegIdx, const VNInfo &ParentVNI) {
494 ValueForcePair &VFP = Values[std::make_pair(RegIdx, ParentVNI.id)];
496495 VNInfo *VNI = VFP.getPointer();
497496
498497 // ParentVNI was either unmapped or already complex mapped. Either way, just
776775 // the source live range. The spiller also won't try to hoist this copy.
777776 if (SpillMode && !SlotIndex::isSameInstr(ParentVNI->def, Idx) &&
778777 MI->readsVirtualRegister(Edit->getReg())) {
779 forceRecompute(0, ParentVNI);
778 forceRecompute(0, *ParentVNI);
780779 defFromParent(0, ParentVNI, Idx, *MI->getParent(), MI);
781780 return Idx;
782781 }
834833
835834 // The complement interval will be extended as needed by LRCalc.extend().
836835 if (ParentVNI)
837 forceRecompute(0, ParentVNI);
836 forceRecompute(0, *ParentVNI);
838837 DEBUG(dbgs() << " overlapIntv [" << Start << ';' << End << "):");
839838 RegAssign.insert(Start, End, OpenIdx);
840839 DEBUG(dump());
877876 unsigned RegIdx = AssignI.value();
878877 if (AtBegin || !MBBI->readsVirtualRegister(Edit->getReg())) {
879878 DEBUG(dbgs() << " cannot find simple kill of RegIdx " << RegIdx << '\n');
880 forceRecompute(RegIdx, Edit->getParent().getVNInfoAt(Def));
879 forceRecompute(RegIdx, *Edit->getParent().getVNInfoAt(Def));
881880 } else {
882881 SlotIndex Kill = LIS.getInstructionIndex(*MBBI).getRegSlot();
883882 DEBUG(dbgs() << " move kill to " << Kill << '\t' << *MBBI);
981980 }
982981 }
983982 if (!DominatedVNIs.empty()) {
984 forceRecompute(0, ParentVNI);
983 forceRecompute(0, *ParentVNI);
985984 for (auto VNI : DominatedVNIs) {
986985 BackCopies.push_back(VNI);
987986 }
11011100 NotToHoistSet.count(ParentVNI->id))
11021101 continue;
11031102 BackCopies.push_back(VNI);
1104 forceRecompute(0, ParentVNI);
1103 forceRecompute(0, *ParentVNI);
11051104 }
11061105
11071106 // If it is not beneficial to hoist all the BackCopies, simply remove
14271426 Edit->eliminateDeadDefs(Dead, None, &AA);
14281427 }
14291428
1429 void SplitEditor::forceRecomputeVNI(const VNInfo &ParentVNI) {
1430 // Fast-path for common case.
1431 if (!ParentVNI.isPHIDef()) {
1432 for (unsigned I = 0, E = Edit->size(); I != E; ++I)
1433 forceRecompute(I, ParentVNI);
1434 return;
1435 }
1436
1437 // Trace value through phis.
1438 SmallPtrSet Visited; ///< whether VNI was/is in worklist.
1439 SmallVector WorkList;
1440 Visited.insert(&ParentVNI);
1441 WorkList.push_back(&ParentVNI);
1442
1443 const LiveInterval &ParentLI = Edit->getParent();
1444 const SlotIndexes &Indexes = *LIS.getSlotIndexes();
1445 do {
1446 const VNInfo &VNI = *WorkList.back();
1447 WorkList.pop_back();
1448 for (unsigned I = 0, E = Edit->size(); I != E; ++I)
1449 forceRecompute(I, VNI);
1450 if (!VNI.isPHIDef())
1451 continue;
1452
1453 MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(VNI.def);
1454 for (const MachineBasicBlock *Pred : MBB.predecessors()) {
1455 SlotIndex PredEnd = Indexes.getMBBEndIdx(Pred);
1456 VNInfo *PredVNI = ParentLI.getVNInfoBefore(PredEnd);
1457 assert(PredVNI && "Value available in PhiVNI predecessor");
1458 if (Visited.insert(PredVNI).second)
1459 WorkList.push_back(PredVNI);
1460 }
1461 } while(!WorkList.empty());
1462 }
1463
14301464 void SplitEditor::finish(SmallVectorImpl *LRMap) {
14311465 ++NumFinished;
14321466
14431477 // Force rematted values to be recomputed everywhere.
14441478 // The new live ranges may be truncated.
14451479 if (Edit->didRematerialize(ParentVNI))
1446 for (unsigned i = 0, e = Edit->size(); i != e; ++i)
1447 forceRecompute(i, ParentVNI);
1480 forceRecomputeVNI(*ParentVNI);
14481481 }
14491482
14501483 // Hoist back-copies to the complement interval when in spill mode.
356356 /// recomputed by LiveRangeCalc::extend regardless of the number of defs.
357357 /// This is used for values whose live range doesn't match RegAssign exactly.
358358 /// They could have rematerialized, or back-copies may have been moved.
359 void forceRecompute(unsigned RegIdx, const VNInfo *ParentVNI);
359 void forceRecompute(unsigned RegIdx, const VNInfo &ParentVNI);
360
361 /// Calls forceRecompute() on any affected regidx and on ParentVNI
362 /// predecessors in case of a phi definition.
363 void forceRecomputeVNI(const VNInfo &ParentVNI);
360364
361365 /// defFromParent - Define Reg from ParentVNI at UseIdx using either
362366 /// rematerialization or a COPY from parent. Return the new value.
0 ; RUN: llc -o - %s | FileCheck %s
1 ; Make sure RegAllocGreedy/SplitKit do not produce invalid liveness information
2 ; and crash when splitting a liverange twice and rematerializing each time.
3 ; (Sorry for the testcase; this was ran through bugpoint and then manually
4 ; reduced for several hours but is still big...)
5 target triple = "thumbv7-apple-ios"
6
7 %struct.ham = type { %struct.wombat.0 }
8 %struct.wombat.0 = type { %struct.barney }
9 %struct.barney = type { %struct.snork.1 }
10 %struct.snork.1 = type { %struct.wobble.2 }
11 %struct.wobble.2 = type { %struct.blam }
12 %struct.blam = type { i32, i32, i8* }
13 %struct.ham.3 = type { %struct.pluto }
14 %struct.pluto = type { %struct.zot*, %struct.snork.5, %struct.wibble }
15 %struct.zot = type { %struct.blam.4* }
16 %struct.blam.4 = type <{ %struct.zot, %struct.blam.4*, %struct.zot*, i8, [3 x i8] }>
17 %struct.snork.5 = type { %struct.quux }
18 %struct.quux = type { %struct.zot }
19 %struct.wibble = type { %struct.widget }
20 %struct.widget = type { i32 }
21 %struct.bar = type { %struct.spam }
22 %struct.spam = type { %struct.zot*, %struct.wobble, %struct.zot.7 }
23 %struct.wobble = type { %struct.wibble.6 }
24 %struct.wibble.6 = type { %struct.zot }
25 %struct.zot.7 = type { %struct.ham.8 }
26 %struct.ham.8 = type { i32 }
27 %struct.hoge = type { %struct.ham, %struct.foo }
28 %struct.foo = type { float, float }
29 %struct.wombat = type { %struct.ham, float }
30 %struct.snork = type { %struct.ham.9, [11 x i8] }
31 %struct.ham.9 = type { i8 }
32
33 @global = external global i8
34 @global.1 = private constant [20 x i8] c"aaaaaaaaaaaaaaaaaa0\00"
35 @global.2 = external constant [27 x i8]
36 @global.3 = external global %struct.ham
37 @global.4 = external constant [47 x i8]
38 @global.5 = external constant [61 x i8]
39 @global.6 = external constant [40 x i8]
40 @global.7 = external constant [24 x i8]
41 @global.8 = external constant [20 x i8]
42 @global.9 = external global %struct.ham
43 @global.10 = external global %struct.ham
44 @global.11 = external global %struct.ham
45 @global.12 = external global %struct.ham
46 @global.13 = external global %struct.ham
47 @global.14 = external global %struct.ham
48 @global.15 = external global %struct.ham
49 @global.16 = external global %struct.ham
50 @global.17 = external global %struct.ham
51 @global.18 = external constant [35 x i8]
52 @global.19 = external global %struct.ham
53 @global.20 = external constant [53 x i8]
54 @global.21 = external global %struct.ham
55 @global.22 = external global %struct.ham
56 @global.23 = external global %struct.ham
57 @global.24 = external constant [32 x i8]
58 @global.25 = external global %struct.ham
59 @global.26 = external constant [47 x i8]
60 @global.27 = external global %struct.ham
61 @global.28 = external constant [45 x i8]
62 @global.29 = external global %struct.ham
63 @global.30 = external global %struct.ham
64 @global.31 = external constant [24 x i8]
65 @global.32 = external global %struct.ham
66 @global.33 = external global %struct.ham
67 @global.34 = external global %struct.ham
68 @global.35 = external global %struct.ham
69 @global.36 = external constant [27 x i8]
70 @global.37 = external global %struct.ham
71 @global.38 = external constant [10 x i8]
72 @global.39 = external global %struct.ham
73 @global.40 = external global %struct.ham
74 @global.41 = external global %struct.ham
75 @global.42 = external global %struct.ham
76 @global.43 = external global %struct.ham
77 @global.44 = external constant [41 x i8]
78 @global.45 = external global %struct.ham
79 @global.46 = external global %struct.ham
80 @global.47 = external global %struct.ham
81 @global.48 = external global %struct.ham
82 @global.49 = external constant [52 x i8]
83 @global.50 = external constant [47 x i8]
84 @global.51 = external global %struct.ham
85 @global.52 = external global %struct.ham
86 @global.53 = external global %struct.ham
87 @global.54 = external global %struct.ham
88 @global.55 = external global %struct.ham.3
89 @global.56 = external global %struct.bar
90 @global.57 = external global i8
91
92 declare %struct.ham* @bar(%struct.ham* returned)
93
94 declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
95
96 declare %struct.ham* @wobble(%struct.ham* returned, %struct.ham* )
97
98 declare i32 @quux(...)
99
100 declare i8* @_Znwm(i32)
101
102 declare i32 @wobble.58(%struct.pluto*, [1 x i32], %struct.ham* , %struct.hoge* )
103
104 declare i32 @widget(%struct.spam*, [1 x i32], %struct.ham* , %struct.wombat* )
105
106 ; Just check we didn't crash and did output something...
107 ; CHECK-LABEL: func:
108 ; CHECK: trap
109 define internal void @func() section "__TEXT,__StaticInit,regular,pure_instructions" personality i32 (...)* @quux {
110 %tmp = tail call i32 @__cxa_atexit(void (i8*)* bitcast (%struct.ham* (%struct.ham*)* @bar to void (i8*)*), i8* bitcast (%struct.ham* @global.3 to i8*), i8* @global) #0
111 %tmp2 = invoke %struct.ham* @wobble(%struct.ham* undef, %struct.ham* @global.9)
112 to label %bb14 unwind label %bbunwind
113
114 bb14:
115 %tmp15 = getelementptr i8, i8* undef, i32 12
116 store i8 0, i8* %tmp15
117 %tmp16 = icmp eq i8 undef, 0
118 br i1 %tmp16, label %bb28, label %bb18
119
120 bb18:
121 br i1 undef, label %bb21, label %bb29
122
123 bb21:
124 %tmp22 = call i8* @_Znwm(i32 16)
125 store i32 17, i32* getelementptr (%struct.ham, %struct.ham* @global.10, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
126 %tmp23 = call i8* @_Znwm(i32 32)
127 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([27 x i8], [27 x i8]* @global.2, i32 0, i32 0), i32 26, i32 1, i1 false)
128 store i32 33, i32* getelementptr (%struct.ham, %struct.ham* @global.11, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
129 store i32 23, i32* getelementptr (%struct.ham, %struct.ham* @global.11, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1)
130 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([24 x i8], [24 x i8]* @global.7, i32 0, i32 0), i32 23, i32 1, i1 false)
131 %tmp24 = call i32 @__cxa_atexit(void (i8*)* bitcast (%struct.ham* (%struct.ham*)* @bar to void (i8*)*), i8* bitcast (%struct.ham* @global.11 to i8*), i8* @global) #0
132 store i32 49, i32* getelementptr (%struct.ham, %struct.ham* @global.12, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
133 store i32 37, i32* getelementptr (%struct.ham, %struct.ham* @global.13, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1)
134 call void @llvm.memset.p0i8.i32(i8* align 4 bitcast (%struct.ham* @global.14 to i8*), i8 0, i32 12, i32 1, i1 false)
135 %tmp25 = call i8* @_Znwm(i32 48)
136 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %tmp25, i8* align 1 getelementptr ([40 x i8], [40 x i8]* @global.6, i32 0, i32 0), i32 39, i32 1, i1 false)
137 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([47 x i8], [47 x i8]* @global.4, i32 0, i32 0), i32 46, i32 1, i1 false)
138 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([61 x i8], [61 x i8]* @global.5, i32 0, i32 0), i32 60, i32 1, i1 false)
139 %tmp26 = call i8* @_Znwm(i32 48)
140 store i32 65, i32* getelementptr (%struct.ham, %struct.ham* @global.15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
141 %tmp27 = icmp eq i8 undef, 0
142 br i1 %tmp27, label %bb30, label %bb33
143
144 bb28:
145 call void @llvm.trap()
146 unreachable
147
148 bb29:
149 call void @llvm.trap()
150 unreachable
151
152 bb30:
153 %tmp31 = icmp eq i32 undef, 37
154 br i1 %tmp31, label %bb32, label %bb30
155
156 bb32:
157 store i8 1, i8* @global.57
158 br label %bb33
159
160 bb33:
161 %tmp34 = call i8* @_Znwm(i32 32)
162 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([20 x i8], [20 x i8]* @global.1, i32 0, i32 0), i32 19, i32 1, i1 false)
163 store i32 17, i32* getelementptr (%struct.ham, %struct.ham* @global.16, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
164 store i32 65, i32* getelementptr (%struct.ham, %struct.ham* @global.17, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
165 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([35 x i8], [35 x i8]* @global.18, i32 0, i32 0), i32 34, i32 1, i1 false)
166 store i32 65, i32* getelementptr (%struct.ham, %struct.ham* @global.19, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
167 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([53 x i8], [53 x i8]* @global.20, i32 0, i32 0), i32 52, i32 1, i1 false)
168 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([20 x i8], [20 x i8]* @global.8, i32 0, i32 0), i32 19, i32 1, i1 false)
169 store i32 37, i32* getelementptr (%struct.ham, %struct.ham* @global.21, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1)
170 %tmp35 = call i8* @_Znwm(i32 32)
171 store i8 16, i8* bitcast (%struct.ham* @global.22 to i8*)
172 %tmp36 = call i8* @_Znwm(i32 32)
173 store i32 31, i32* getelementptr (%struct.ham, %struct.ham* @global.23, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1)
174 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %tmp36, i8* align 1 getelementptr ([32 x i8], [32 x i8]* @global.24, i32 0, i32 0), i32 31, i32 1, i1 false)
175 %tmp37 = getelementptr i8, i8* %tmp36, i32 31
176 store i8 0, i8* %tmp37
177 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([47 x i8], [47 x i8]* @global.26, i32 0, i32 0), i32 46, i32 1, i1 false)
178 %tmp38 = call i32 @__cxa_atexit(void (i8*)* bitcast (%struct.ham* (%struct.ham*)* @bar to void (i8*)*), i8* bitcast (%struct.ham* @global.25 to i8*), i8* @global) #0
179 %tmp39 = call i8* @_Znwm(i32 48)
180 store i32 44, i32* getelementptr (%struct.ham, %struct.ham* @global.27, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1)
181 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %tmp39, i8* align 1 getelementptr ([45 x i8], [45 x i8]* @global.28, i32 0, i32 0), i32 44, i32 1, i1 false)
182 %tmp40 = getelementptr i8, i8* %tmp39, i32 44
183 store i8 0, i8* %tmp40
184 call void @llvm.memset.p0i8.i32(i8* align 4 bitcast (%struct.ham* @global.29 to i8*), i8 0, i32 12, i32 1, i1 false)
185 %tmp41 = call i8* @_Znwm(i32 32)
186 store i32 23, i32* getelementptr (%struct.ham, %struct.ham* @global.30, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1)
187 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %tmp41, i8* align 1 getelementptr ([24 x i8], [24 x i8]* @global.31, i32 0, i32 0), i32 23, i32 1, i1 false)
188 %tmp42 = getelementptr i8, i8* %tmp41, i32 23
189 store i8 0, i8* %tmp42
190 call void @llvm.memset.p0i8.i32(i8* align 4 bitcast (%struct.ham* @global.32 to i8*), i8 0, i32 12, i32 1, i1 false)
191 store i8 16, i8* bitcast (%struct.ham* @global.32 to i8*)
192 %tmp43 = call i32 @__cxa_atexit(void (i8*)* bitcast (%struct.ham* (%struct.ham*)* @bar to void (i8*)*), i8* bitcast (%struct.ham* @global.33 to i8*), i8* @global) #0
193 %tmp44 = call i8* @_Znwm(i32 16)
194 call void @llvm.memset.p0i8.i32(i8* align 4 bitcast (%struct.ham* @global.34 to i8*), i8 0, i32 12, i32 1, i1 false)
195 call void @llvm.memset.p0i8.i32(i8* align 4 bitcast (%struct.ham* @global.9 to i8*), i8 0, i32 12, i32 1, i1 false)
196 %tmp45 = call i8* @_Znwm(i32 32)
197 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %tmp45, i8* align 1 getelementptr ([27 x i8], [27 x i8]* @global.36, i32 0, i32 0), i32 26, i32 1, i1 false)
198 call void @llvm.memset.p0i8.i32(i8* align 4 bitcast (%struct.ham* @global.37 to i8*), i8 0, i32 12, i32 1, i1 false)
199 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 getelementptr (%struct.snork, %struct.snork* bitcast (%struct.ham* @global.37 to %struct.snork*), i32 0, i32 1, i32 0), i8* align 1 getelementptr ([10 x i8], [10 x i8]* @global.38, i32 0, i32 0), i32 9, i32 1, i1 false)
200 store i32 17, i32* getelementptr (%struct.ham, %struct.ham* @global.39, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
201 %tmp46 = call i32 @__cxa_atexit(void (i8*)* bitcast (%struct.ham* (%struct.ham*)* @bar to void (i8*)*), i8* bitcast (%struct.ham* @global.40 to i8*), i8* @global) #0
202 %tmp47 = call i8* @_Znwm(i32 32)
203 %tmp48 = getelementptr i8, i8* %tmp47, i32 21
204 store i8 0, i8* %tmp48
205 store i32 33, i32* getelementptr (%struct.ham, %struct.ham* @global.41, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
206 store i32 15, i32* getelementptr (%struct.ham, %struct.ham* @global.42, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1)
207 %tmp49 = call i32 @__cxa_atexit(void (i8*)* bitcast (%struct.ham* (%struct.ham*)* @bar to void (i8*)*), i8* bitcast (%struct.ham* @global.43 to i8*), i8* @global) #0
208 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([41 x i8], [41 x i8]* @global.44, i32 0, i32 0), i32 40, i32 1, i1 false)
209 %tmp50 = call i32 @__cxa_atexit(void (i8*)* bitcast (%struct.ham* (%struct.ham*)* @bar to void (i8*)*), i8* bitcast (%struct.ham* @global.45 to i8*), i8* @global) #0
210 %tmp51 = call i32 @__cxa_atexit(void (i8*)* bitcast (%struct.ham* (%struct.ham*)* @bar to void (i8*)*), i8* bitcast (%struct.ham* @global.46 to i8*), i8* @global) #0
211 %tmp52 = call i8* @_Znwm(i32 32)
212 store i8* %tmp52, i8** getelementptr (%struct.ham, %struct.ham* @global.47, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 2)
213 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([52 x i8], [52 x i8]* @global.49, i32 0, i32 0), i32 51, i32 1, i1 false)
214 %tmp53 = call i32 @__cxa_atexit(void (i8*)* bitcast (%struct.ham* (%struct.ham*)* @bar to void (i8*)*), i8* bitcast (%struct.ham* @global.48 to i8*), i8* @global) #0
215 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 undef, i8* align 1 getelementptr ([47 x i8], [47 x i8]* @global.50, i32 0, i32 0), i32 46, i32 1, i1 false)
216 store i32 33, i32* getelementptr (%struct.ham, %struct.ham* @global.51, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
217 store i32 37, i32* getelementptr (%struct.ham, %struct.ham* @global.52, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1)
218 %tmp54 = invoke %struct.ham* @wobble(%struct.ham* undef, %struct.ham* @global.54)
219 to label %bb58 unwind label %bbunwind
220
221 bb58:
222 %tmp59 = invoke i32 @wobble.58(%struct.pluto* getelementptr (%struct.ham.3, %struct.ham.3* @global.55, i32 0, i32 0), [1 x i32] [i32 ptrtoint (%struct.zot* getelementptr (%struct.ham.3, %struct.ham.3* @global.55, i32 0, i32 0, i32 1, i32 0, i32 0) to i32)], %struct.ham* undef, %struct.hoge* undef)
223 to label %bb71 unwind label %bbunwind
224
225 bb71:
226 %tmp72 = invoke i32 @widget(%struct.spam* getelementptr (%struct.bar, %struct.bar* @global.56, i32 0, i32 0), [1 x i32] [i32 ptrtoint (%struct.zot* getelementptr (%struct.bar, %struct.bar* @global.56, i32 0, i32 0, i32 1, i32 0, i32 0) to i32)], %struct.ham* undef, %struct.wombat* undef)
227 to label %bb73 unwind label %bbunwind
228
229 bb73:
230 ret void
231
232 bbunwind:
233 %tmp75 = landingpad { i8*, i32 }
234 cleanup
235 resume { i8*, i32 } undef
236 }
237
238 declare void @llvm.trap()
239
240 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* , i8* , i32, i32, i1)
241
242 declare void @llvm.memset.p0i8.i32(i8* , i8, i32, i32, i1)
243
244 attributes #0 = { nounwind }