llvm.org GIT mirror llvm / 4784f1f
Add a bit IsUndef to MachineOperand. This indicates the def / use register operand is defined by an implicit_def. That means it can def / use any register and passes (e.g. register scavenger) can feel free to ignore them. The register allocator, when it allocates a register to a virtual register defined by an implicit_def, can allocate any physical register without worrying about overlapping live ranges. It should mark all of operands of the said virtual register so later passes will do the right thing. This is not the best solution. But it should be a lot less fragile to having the scavenger try to track what is defined by implicit_def. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74518 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 10 years ago
11 changed file(s) with 214 addition(s) and 80 deletion(s). Raw diff Collapse all Expand all
2828 Implicit = 0x4,
2929 Kill = 0x8,
3030 Dead = 0x10,
31 EarlyClobber = 0x20,
31 Undef = 0x20,
32 EarlyClobber = 0x40,
3233 ImplicitDefine = Implicit | Define,
3334 ImplicitKill = Implicit | Kill
3435 };
5657 flags & RegState::Implicit,
5758 flags & RegState::Kill,
5859 flags & RegState::Dead,
59 SubReg,
60 flags & RegState::EarlyClobber));
60 flags & RegState::Undef,
61 flags & RegState::EarlyClobber,
62 SubReg));
6163 return *this;
6264 }
6365
202204 inline unsigned getDeadRegState(bool B) {
203205 return B ? RegState::Dead : 0;
204206 }
207 inline unsigned getUndefRegState(bool B) {
208 return B ? RegState::Undef : 0;
209 }
205210
206211 } // End llvm namespace
207212
7373 /// IsDead - True if this register is never used by a subsequent instruction.
7474 /// This is only valid on definitions of registers.
7575 bool IsDead : 1;
76
77 /// IsUndef - True if this is a register def / use of "undef", i.e. register
78 /// defined by an IMPLICIT_DEF. This is only valid on registers.
79 bool IsUndef : 1;
7680
7781 /// IsEarlyClobber - True if this MO_Register 'def' operand is written to
7882 /// by the MachineInstr before all input registers are read. This is used to
197201 return IsKill;
198202 }
199203
204 bool isUndef() const {
205 assert(isReg() && "Wrong MachineOperand accessor");
206 return IsUndef;
207 }
208
200209 bool isEarlyClobber() const {
201210 assert(isReg() && "Wrong MachineOperand accessor");
202211 return IsEarlyClobber;
247256 IsDead = Val;
248257 }
249258
259 void setIsUndef(bool Val = true) {
260 assert(isReg() && "Wrong MachineOperand accessor");
261 IsUndef = Val;
262 }
263
250264 void setIsEarlyClobber(bool Val = true) {
251265 assert(isReg() && IsDef && "Wrong MachineOperand accessor");
252266 IsEarlyClobber = Val;
336350 /// the specified value. If an operand is known to be an register already,
337351 /// the setReg method should be used.
338352 void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
339 bool isKill = false, bool isDead = false);
353 bool isKill = false, bool isDead = false,
354 bool isUndef = false);
340355
341356 //===--------------------------------------------------------------------===//
342357 // Construction methods.
356371
357372 static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false,
358373 bool isKill = false, bool isDead = false,
359 unsigned SubReg = 0,
360 bool isEarlyClobber = false) {
374 bool isUndef = false,
375 bool isEarlyClobber = false,
376 unsigned SubReg = 0) {
361377 MachineOperand Op(MachineOperand::MO_Register);
362378 Op.IsDef = isDef;
363379 Op.IsImp = isImp;
364380 Op.IsKill = isKill;
365381 Op.IsDead = isDead;
382 Op.IsUndef = isUndef;
366383 Op.IsEarlyClobber = isEarlyClobber;
367384 Op.Contents.Reg.RegNo = Reg;
368385 Op.Contents.Reg.Prev = 0;
419436 IsImp = MO.IsImp;
420437 IsKill = MO.IsKill;
421438 IsDead = MO.IsDead;
439 IsUndef = MO.IsUndef;
422440 IsEarlyClobber = MO.IsEarlyClobber;
423441 SubReg = MO.SubReg;
424442 ParentMI = MO.ParentMI;
6868 /// available, unset means the register is currently being used.
6969 BitVector RegsAvailable;
7070
71 /// ImplicitDefed - If bit is set that means the register is defined by an
72 /// implicit_def instructions. That means it can be clobbered at will.
73 BitVector ImplicitDefed;
74
7571 /// CurrDist - Distance from MBB entry to the current instruction MBBI.
7672 ///
7773 unsigned CurrDist;
116112 bool isUsed(unsigned Reg) const { return !RegsAvailable[Reg]; }
117113 bool isUnused(unsigned Reg) const { return RegsAvailable[Reg]; }
118114
119 bool isImplicitlyDefined(unsigned Reg) const { return ImplicitDefed[Reg]; }
120
121115 /// getRegsUsed - return all registers currently in use in used.
122116 void getRegsUsed(BitVector &used, bool includeReserved);
123117
124118 /// setUsed / setUnused - Mark the state of one or a number of registers.
125119 ///
126 void setUsed(unsigned Reg, bool ImpDef = false);
127 void setUsed(BitVector &Regs, bool ImpDef = false) {
120 void setUsed(unsigned Reg);
121 void setUsed(BitVector &Regs) {
128122 RegsAvailable &= ~Regs;
129 if (ImpDef)
130 ImplicitDefed |= Regs;
131 else
132 ImplicitDefed &= ~Regs;
133123 }
134124 void setUnused(unsigned Reg, const MachineInstr *MI);
135125 void setUnused(BitVector &Regs) {
136126 RegsAvailable |= Regs;
137 ImplicitDefed &= ~Regs;
138127 }
139128
140129 /// FindUnusedReg - Find a unused register of the specified register class
17811781 NewLIs.push_back(&getOrCreateInterval(NewVReg));
17821782 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
17831783 MachineOperand &MO = MI->getOperand(i);
1784 if (MO.isReg() && MO.getReg() == li.reg)
1784 if (MO.isReg() && MO.getReg() == li.reg) {
17851785 MO.setReg(NewVReg);
1786 MO.setIsUndef();
1787 if (MO.isKill())
1788 MO.setIsKill(false);
1789 }
17861790 }
17871791 }
17881792 }
119119 /// the specified value. If an operand is known to be an register already,
120120 /// the setReg method should be used.
121121 void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
122 bool isKill, bool isDead) {
122 bool isKill, bool isDead, bool isUndef) {
123123 // If this operand is already a register operand, use setReg to update the
124124 // register's use/def lists.
125125 if (isReg()) {
142142 IsImp = isImp;
143143 IsKill = isKill;
144144 IsDead = isDead;
145 IsUndef = isUndef;
145146 IsEarlyClobber = false;
146147 SubReg = 0;
147148 }
205206 OS << "%mreg" << getReg();
206207 }
207208
208 if (getSubReg() != 0) {
209 if (getSubReg() != 0)
209210 OS << ':' << getSubReg();
210 }
211
212 if (isDef() || isKill() || isDead() || isImplicit() || isEarlyClobber()) {
211
212 if (isDef() || isKill() || isDead() || isImplicit() || isUndef() ||
213 isEarlyClobber()) {
213214 OS << '<';
214215 bool NeedComma = false;
215216 if (isImplicit()) {
223224 OS << "def";
224225 NeedComma = true;
225226 }
226 if (isKill() || isDead()) {
227 if (isKill() || isDead() || isUndef()) {
227228 if (NeedComma) OS << ',';
228229 if (isKill()) OS << "kill";
229230 if (isDead()) OS << "dead";
231 if (isUndef()) {
232 if (isKill() || isDead())
233 OS << ',';
234 OS << "undef";
235 }
230236 }
231237 OS << '>';
232238 }
904904 DOUT << tri_->getName(physReg) << '\n';
905905 // Note the register is not really in use.
906906 vrm_->assignVirt2Phys(cur->reg, physReg);
907 // Since the register allocator is allowed to assign this virtual register
908 // physical register that overlaps other live intervals. Mark these
909 // operands as "Undef" which means later passes, e.g. register scavenger
910 // can ignore them.
911 for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(cur->reg),
912 RE = mri_->reg_end(); RI != RE; ++RI) {
913 MachineOperand &MO = RI.getOperand();
914 MO.setIsUndef();
915 if (MO.isKill())
916 MO.setIsKill(false);
917 }
907918 return;
908919 }
909920
3535 bool SeenSuperDef = false;
3636 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
3737 const MachineOperand &MO = MI->getOperand(i);
38 if (!MO.isReg())
38 if (!MO.isReg() || MO.isUndef())
3939 continue;
4040 if (TRI->isSuperRegister(SubReg, MO.getReg())) {
4141 if (MO.isUse())
5656 }
5757
5858 /// setUsed - Set the register and its sub-registers as being used.
59 void RegScavenger::setUsed(unsigned Reg, bool ImpDef) {
59 void RegScavenger::setUsed(unsigned Reg) {
6060 RegsAvailable.reset(Reg);
61 ImplicitDefed[Reg] = ImpDef;
6261
6362 for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
64 unsigned SubReg = *SubRegs; ++SubRegs) {
63 unsigned SubReg = *SubRegs; ++SubRegs)
6564 RegsAvailable.reset(SubReg);
66 ImplicitDefed[SubReg] = ImpDef;
67 }
6865 }
6966
7067 /// setUnused - Set the register and its sub-registers as being unused.
7168 void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) {
7269 RegsAvailable.set(Reg);
73 ImplicitDefed.reset(Reg);
7470
7571 for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
7672 unsigned SubReg = *SubRegs; ++SubRegs)
77 if (!RedefinesSuperRegPart(MI, Reg, TRI)) {
73 if (!RedefinesSuperRegPart(MI, Reg, TRI))
7874 RegsAvailable.set(SubReg);
79 ImplicitDefed.reset(SubReg);
80 }
8175 }
8276
8377 void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
9387 if (!MBB) {
9488 NumPhysRegs = TRI->getNumRegs();
9589 RegsAvailable.resize(NumPhysRegs);
96 ImplicitDefed.resize(NumPhysRegs);
9790
9891 // Create reserved registers bitvector.
9992 ReservedRegs = TRI->getReservedRegs(MF);
112105 ScavengeRestore = NULL;
113106 CurrDist = 0;
114107 DistanceMap.clear();
115 ImplicitDefed.reset();
116108
117109 // All registers started out unused.
118110 RegsAvailable.set();
194186 ScavengeRestore = NULL;
195187 }
196188
197 bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF;
198
199189 // Separate register operands into 3 classes: uses, defs, earlyclobbers.
200190 SmallVector, 4> UseMOs;
201191 SmallVector, 4> DefMOs;
202192 SmallVector, 4> EarlyClobberMOs;
203193 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
204194 const MachineOperand &MO = MI->getOperand(i);
205 if (!MO.isReg() || MO.getReg() == 0)
195 if (!MO.isReg() || MO.getReg() == 0 || MO.isUndef())
206196 continue;
207197 if (MO.isUse())
208198 UseMOs.push_back(std::make_pair(&MO,i));
220210
221211 assert(isUsed(Reg) && "Using an undefined register!");
222212
223 // Kill of implicit_def defined registers are ignored. e.g.
224 // entry: 0x2029ab8, LLVM BB @0x1b06080, ID#0:
225 // Live Ins: %R0
226 // %R0 = IMPLICIT_DEF
227 // %R0 = IMPLICIT_DEF
228 // STR %R0, %R0, %reg0, 0, 14, %reg0, Mem:ST(4,4) [0x1b06510 + 0]
229 // %R1 = LDR %R0, %reg0, 24, 14, %reg0, Mem:LD(4,4) [0x1b065bc + 0]
230 if (MO.isKill() && !isReserved(Reg) && !isImplicitlyDefined(Reg)) {
213 if (MO.isKill() && !isReserved(Reg)) {
231214 KillRegs.set(Reg);
232215
233216 // Mark sub-registers as used.
273256 // Implicit def is allowed to "re-define" any register. Similarly,
274257 // implicitly defined registers can be clobbered.
275258 assert((isReserved(Reg) || isUnused(Reg) ||
276 IsImpDef || isImplicitlyDefined(Reg) ||
277259 isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) &&
278260 "Re-defining a live register!");
279 setUsed(Reg, IsImpDef);
261 setUsed(Reg);
280262 }
281263 }
282264
296278 SmallVector, 4> EarlyClobberMOs;
297279 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
298280 const MachineOperand &MO = MI->getOperand(i);
299 if (!MO.isReg() || MO.getReg() == 0)
281 if (!MO.isReg() || MO.getReg() == 0 || MO.isUndef())
300282 continue;
301283 if (MO.isUse())
302284 UseMOs.push_back(std::make_pair(&MO,i));
616616 for (; NumVals; --NumVals, ++i) {
617617 unsigned Reg = cast(Node->getOperand(i))->getReg();
618618 MI->addOperand(MachineOperand::CreateReg(Reg, true, false, false,
619 false, 0, true));
619 false, false, true));
620620 }
621621 break;
622622 case 1: // Use of register.
355355 SmallVector *KillRegs = NULL) {
356356 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
357357 MachineOperand &MO = MI.getOperand(i);
358 if (!MO.isReg() || !MO.isUse() || !MO.isKill())
358 if (!MO.isReg() || !MO.isUse() || !MO.isKill() || MO.isUndef())
359359 continue;
360360 unsigned Reg = MO.getReg();
361361 if (TargetRegisterInfo::isVirtualRegister(Reg))
389389 MachineOperand *DefOp = NULL;
390390 for (unsigned i = 0, e = DefMI->getNumOperands(); i != e; ++i) {
391391 MachineOperand &MO = DefMI->getOperand(i);
392 if (MO.isReg() && MO.isDef()) {
393 if (MO.getReg() == Reg)
394 DefOp = &MO;
395 else if (!MO.isDead())
396 HasLiveDef = true;
397 }
392 if (!MO.isReg() || !MO.isUse() || !MO.isKill() || MO.isUndef())
393 continue;
394 if (MO.getReg() == Reg)
395 DefOp = &MO;
396 else if (!MO.isDead())
397 HasLiveDef = true;
398398 }
399399 if (!DefOp)
400400 return false;
429429 std::vector &KillOps) {
430430 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
431431 MachineOperand &MO = MI.getOperand(i);
432 if (!MO.isReg() || !MO.isUse())
432 if (!MO.isReg() || !MO.isUse() || MO.isUndef())
433433 continue;
434434 unsigned Reg = MO.getReg();
435435 if (Reg == 0)
12881288 if (InvalidateRegDef(PrevMII, *MII, KillRegs[j], HasOtherDef)) {
12891289 MachineInstr *DeadDef = PrevMII;
12901290 if (ReMatDefs.count(DeadDef) && !HasOtherDef) {
1291 // FIXME: This assumes a remat def does not have side
1292 // effects.
1291 // FIXME: This assumes a remat def does not have side effects.
12931292 VRM.RemoveMachineInstrFromMaps(DeadDef);
12941293 MBB.erase(DeadDef);
12951294 ++NumDRM;
15681567 if (MO.isImplicit())
15691568 // If the virtual register is implicitly defined, emit a implicit_def
15701569 // before so scavenger knows it's "defined".
1570 // FIXME: This is a horrible hack done the by register allocator to
1571 // remat a definition with virtual register operand.
15711572 VirtUseOps.insert(VirtUseOps.begin(), i);
15721573 else
15731574 VirtUseOps.push_back(i);
15941595 MI.getOperand(i).setReg(RReg);
15951596 MI.getOperand(i).setSubReg(0);
15961597 if (VRM.isImplicitlyDefined(VirtReg))
1598 // FIXME: Is this needed?
15971599 BuildMI(MBB, &MI, MI.getDebugLoc(),
15981600 TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
15991601 continue;
16031605 if (!MO.isUse())
16041606 continue; // Handle defs in the loop below (handle use&def here though)
16051607
1606 bool AvoidReload = false;
1607 if (LIs->hasInterval(VirtReg)) {
1608 LiveInterval &LI = LIs->getInterval(VirtReg);
1609 if (!LI.liveAt(LIs->getUseIndex(LI.beginNumber())))
1610 // Must be defined by an implicit def. It should not be spilled. Note,
1611 // this is for correctness reason. e.g.
1612 // 8 %reg1024 = IMPLICIT_DEF
1613 // 12 %reg1024 = INSERT_SUBREG %reg1024, %reg1025, 2
1614 // The live range [12, 14) are not part of the r1024 live interval since
1615 // it's defined by an implicit def. It will not conflicts with live
1616 // interval of r1025. Now suppose both registers are spilled, you can
1617 // easily see a situation where both registers are reloaded before
1618 // the INSERT_SUBREG and both target registers that would overlap.
1619 AvoidReload = true;
1620 }
1621
1608 bool AvoidReload = MO.isUndef();
1609 // Check if it is defined by an implicit def. It should not be spilled.
1610 // Note, this is for correctness reason. e.g.
1611 // 8 %reg1024 = IMPLICIT_DEF
1612 // 12 %reg1024 = INSERT_SUBREG %reg1024, %reg1025, 2
1613 // The live range [12, 14) are not part of the r1024 live interval since
1614 // it's defined by an implicit def. It will not conflicts with live
1615 // interval of r1025. Now suppose both registers are spilled, you can
1616 // easily see a situation where both registers are reloaded before
1617 // the INSERT_SUBREG and both target registers that would overlap.
16221618 bool DoReMat = VRM.isReMaterialized(VirtReg);
16231619 int SSorRMId = DoReMat
16241620 ? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg);
24582458 getDefRegState(MO.isDef()) |
24592459 RegState::Implicit |
24602460 getKillRegState(MO.isKill()) |
2461 getDeadRegState(MO.isDead()));
2461 getDeadRegState(MO.isDead()) |
2462 getUndefRegState(MO.isUndef()));
24622463 }
24632464 // Change CMP32ri r, 0 back to TEST32rr r, r, etc.
24642465 unsigned NewOpc = 0;
0 ; RUN: llvm-as < %s | llc -march=arm -mtriple=armv6-apple-darwin9
1
2 @nn = external global i32 ; [#uses=1]
3 @al_len = external global i32 ; [#uses=2]
4 @no_mat = external global i32 ; [#uses=2]
5 @no_mis = external global i32 ; [#uses=2]
6 @"\01LC12" = external constant [29 x i8], align 1 ; <[29 x i8]*> [#uses=1]
7 @"\01LC16" = external constant [33 x i8], align 1 ; <[33 x i8]*> [#uses=1]
8 @"\01LC17" = external constant [47 x i8], align 1 ; <[47 x i8]*> [#uses=1]
9
10 declare arm_apcscc i32 @printf(i8* nocapture, ...) nounwind
11
12 declare arm_apcscc void @diff(i8*, i8*, i32, i32, i32, i32) nounwind
13
14 define arm_apcscc void @SIM(i8* %A, i8* %B, i32 %M, i32 %N, i32 %K, [256 x i32]* %V, i32 %Q, i32 %R, i32 %nseq) nounwind {
15 entry:
16 br i1 undef, label %bb5, label %bb
17
18 bb: ; preds = %bb, %entry
19 br label %bb
20
21 bb5: ; preds = %entry
22 br i1 undef, label %bb6, label %bb8
23
24 bb6: ; preds = %bb6, %bb5
25 br i1 undef, label %bb8, label %bb6
26
27 bb8: ; preds = %bb6, %bb5
28 br label %bb15
29
30 bb9: ; preds = %bb15
31 br i1 undef, label %bb10, label %bb11
32
33 bb10: ; preds = %bb9
34 unreachable
35
36 bb11: ; preds = %bb9
37 %0 = load i32* undef, align 4 ; [#uses=2]
38 %1 = add i32 %0, 1 ; [#uses=2]
39 store i32 %1, i32* undef, align 4
40 %2 = load i32* undef, align 4 ; [#uses=1]
41 store i32 %2, i32* @nn, align 4
42 store i32 0, i32* @al_len, align 4
43 store i32 0, i32* @no_mat, align 4
44 store i32 0, i32* @no_mis, align 4
45 %3 = getelementptr i8* %B, i32 %0 ; [#uses=1]
46 tail call arm_apcscc void @diff(i8* undef, i8* %3, i32 undef, i32 undef, i32 undef, i32 undef) nounwind
47 %4 = sitofp i32 undef to double ; [#uses=1]
48 %5 = fdiv double %4, 1.000000e+01 ; [#uses=1]
49 %6 = tail call arm_apcscc i32 (i8*, ...)* @printf(i8* getelementptr ([29 x i8]* @"\01LC12", i32 0, i32 0), double %5) nounwind ; [#uses=0]
50 %7 = load i32* @al_len, align 4 ; [#uses=1]
51 %8 = load i32* @no_mat, align 4 ; [#uses=1]
52 %9 = load i32* @no_mis, align 4 ; [#uses=1]
53 %10 = sub i32 %7, %8 ; [#uses=1]
54 %11 = sub i32 %10, %9 ; [#uses=1]
55 %12 = tail call arm_apcscc i32 (i8*, ...)* @printf(i8* getelementptr ([33 x i8]* @"\01LC16", i32 0, i32 0), i32 %11) nounwind ; [#uses=0]
56 %13 = tail call arm_apcscc i32 (i8*, ...)* @printf(i8* getelementptr ([47 x i8]* @"\01LC17", i32 0, i32 0), i32 undef, i32 %1, i32 undef, i32 undef) nounwind ; [#uses=0]
57 br i1 undef, label %bb15, label %bb12
58
59 bb12: ; preds = %bb11
60 br label %bb228.i
61
62 bb74.i: ; preds = %bb228.i
63 br i1 undef, label %bb138.i, label %bb145.i
64
65 bb138.i: ; preds = %bb74.i
66 br label %bb145.i
67
68 bb145.i: ; preds = %bb228.i, %bb138.i, %bb74.i
69 br i1 undef, label %bb146.i, label %bb151.i
70
71 bb146.i: ; preds = %bb145.i
72 br i1 undef, label %bb228.i, label %bb151.i
73
74 bb151.i: ; preds = %bb146.i, %bb145.i
75 br i1 undef, label %bb153.i, label %bb228.i
76
77 bb153.i: ; preds = %bb151.i
78 br i1 undef, label %bb220.i, label %bb.nph.i98
79
80 bb.nph.i98: ; preds = %bb153.i
81 br label %bb158.i
82
83 bb158.i: ; preds = %bb218.i, %bb.nph.i98
84 br i1 undef, label %bb168.i, label %bb160.i
85
86 bb160.i: ; preds = %bb158.i
87 br i1 undef, label %bb161.i, label %bb168.i
88
89 bb161.i: ; preds = %bb160.i
90 br i1 undef, label %bb168.i, label %bb163.i
91
92 bb163.i: ; preds = %bb161.i
93 br i1 undef, label %bb167.i, label %bb168.i
94
95 bb167.i: ; preds = %bb163.i
96 br label %bb168.i
97
98 bb168.i: ; preds = %bb167.i, %bb163.i, %bb161.i, %bb160.i, %bb158.i
99 br i1 undef, label %bb211.i, label %bb218.i
100
101 bb211.i: ; preds = %bb168.i
102 br label %bb218.i
103
104 bb218.i: ; preds = %bb211.i, %bb168.i
105 br i1 undef, label %bb220.i, label %bb158.i
106
107 bb220.i: ; preds = %bb218.i, %bb153.i
108 br i1 undef, label %bb221.i, label %bb228.i
109
110 bb221.i: ; preds = %bb220.i
111 br label %bb228.i
112
113 bb228.i: ; preds = %bb221.i, %bb220.i, %bb151.i, %bb146.i, %bb12
114 br i1 undef, label %bb74.i, label %bb145.i
115
116 bb15: ; preds = %bb11, %bb8
117 br i1 undef, label %return, label %bb9
118
119 return: ; preds = %bb15
120 ret void
121 }