llvm.org GIT mirror llvm / f6b4a03
[RuntimeUnrolling] Add logic for loops with multiple exit blocks Summary: Runtime unrolling is done for loops with a single exit block and a single exiting block (and this exiting block should be the latch block). This patch adds logic to support unrolling in the presence of multiple exit blocks (which also means multiple exiting blocks). Currently this is under an off-by-default option and is supported when epilog code is generated. Support in presence of prolog code will be in a future patch (we just need to add more tests, and update comments). This patch is essentially an implementation patch. I have not added any heuristic (in terms of branches added or code size) to decide when this should be enabled. Reviewers: mkuper, sanjoy, reames, evstupac Reviewed by: reames Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33001 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306846 91177308-0d34-0410-b5e6-96231b3b80d8 Anna Thomas 2 years ago
2 changed file(s) with 381 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
3535 #include "llvm/Transforms/Scalar.h"
3636 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
3737 #include "llvm/Transforms/Utils/Cloning.h"
38 #include "llvm/Transforms/Utils/LoopUtils.h"
3839 #include "llvm/Transforms/Utils/UnrollLoop.h"
3940 #include
4041
4445
4546 STATISTIC(NumRuntimeUnrolled,
4647 "Number of loops unrolled with run-time trip counts");
48 static cl::opt UnrollRuntimeMultiExit(
49 "unroll-runtime-multi-exit", cl::init(false), cl::Hidden,
50 cl::desc("Allow runtime unrolling for loops with multiple exits, when "
51 "epilog is generated"));
4752
4853 /// Connect the unrolling prolog code to the original loop.
4954 /// The unrolling prolog code contains code to execute the
284289 /// The cloned blocks should be inserted between InsertTop and InsertBot.
285290 /// If loop structure is cloned InsertTop should be new preheader, InsertBot
286291 /// new loop exit.
287 ///
288 static void CloneLoopBlocks(Loop *L, Value *NewIter,
289 const bool CreateRemainderLoop,
290 const bool UseEpilogRemainder,
291 BasicBlock *InsertTop, BasicBlock *InsertBot,
292 BasicBlock *Preheader,
293 std::vector &NewBlocks,
294 LoopBlocksDFS &LoopBlocks, ValueToValueMapTy &VMap,
295 DominatorTree *DT, LoopInfo *LI) {
292 /// Return the new cloned loop that is created when CreateRemainderLoop is true.
293 static Loop *
294 CloneLoopBlocks(Loop *L, Value *NewIter, const bool CreateRemainderLoop,
295 const bool UseEpilogRemainder, BasicBlock *InsertTop,
296 BasicBlock *InsertBot, BasicBlock *Preheader,
297 std::vector &NewBlocks, LoopBlocksDFS &LoopBlocks,
298 ValueToValueMapTy &VMap, DominatorTree *DT, LoopInfo *LI) {
296299 StringRef suffix = UseEpilogRemainder ? "epil" : "prol";
297300 BasicBlock *Header = L->getHeader();
298301 BasicBlock *Latch = L->getLoopLatch();
417420 // Set operand 0 to refer to the loop id itself.
418421 NewLoopID->replaceOperandWith(0, NewLoopID);
419422 NewLoop->setLoopID(NewLoopID);
420 }
423 return NewLoop;
424 }
425 else
426 return nullptr;
421427 }
422428
423429 /// Insert code in the prolog/epilog code when unrolling a loop with a
464470 LoopInfo *LI, ScalarEvolution *SE,
465471 DominatorTree *DT, bool PreserveLCSSA) {
466472 // for now, only unroll loops that contain a single exit
467 if (!L->getExitingBlock())
473 if (!UnrollRuntimeMultiExit && !L->getExitingBlock())
468474 return false;
469475
470 // Make sure the loop is in canonical form, and there is a single
471 // exit block only.
476 // Make sure the loop is in canonical form.
472477 if (!L->isLoopSimplifyForm())
473478 return false;
474479
475480 // Guaranteed by LoopSimplifyForm.
476481 BasicBlock *Latch = L->getLoopLatch();
482 BasicBlock *Header = L->getHeader();
477483
478484 BasicBlock *LatchExit = L->getUniqueExitBlock(); // successor out of loop
479 if (!LatchExit)
485 if (!LatchExit && !UnrollRuntimeMultiExit)
480486 return false;
487 // These are exit blocks other than the target of the latch exiting block.
488 SmallVector OtherExits;
489 BranchInst *LatchBR = cast(Latch->getTerminator());
490 unsigned int ExitIndex = LatchBR->getSuccessor(0) == Header ? 1 : 0;
481491 // Cloning the loop basic blocks (`CloneLoopBlocks`) requires that one of the
482 // targets of the Latch be the single exit block out of the loop. This needs
492 // targets of the Latch be an exit block out of the loop. This needs
483493 // to be guaranteed by the callers of UnrollRuntimeLoopRemainder.
484 BranchInst *LatchBR = cast(Latch->getTerminator());
485 assert((LatchBR->getSuccessor(0) == LatchExit ||
486 LatchBR->getSuccessor(1) == LatchExit) &&
487 "one of the loop latch successors should be "
488 "the exit block!");
489 (void)LatchBR;
494 assert(!L->contains(LatchBR->getSuccessor(ExitIndex)) &&
495 "one of the loop latch successors should be the exit block!");
496 // Support runtime unrolling for multiple exit blocks and multiple exiting
497 // blocks.
498 if (!LatchExit) {
499 assert(UseEpilogRemainder && "Multi exit unrolling is currently supported "
500 "unrolling with epilog remainder only!");
501 LatchExit = LatchBR->getSuccessor(ExitIndex);
502 // We rely on LCSSA form being preserved when the exit blocks are
503 // transformed.
504 if (!PreserveLCSSA)
505 return false;
506 // TODO: Support multiple exiting blocks jumping to the `LatchExit`. This
507 // will need updating the logic in connectEpilog.
508 if (!LatchExit->getSinglePredecessor())
509 return false;
510 SmallVector Exits;
511 L->getUniqueExitBlocks(Exits);
512 for (auto *BB : Exits)
513 if (BB != LatchExit)
514 OtherExits.push_back(BB);
515 }
516
517 assert(LatchExit && "Latch Exit should exist!");
518
490519 // Use Scalar Evolution to compute the trip count. This allows more loops to
491520 // be unrolled than relying on induction var simplification.
492521 if (!SE)
511540 if (isa(TripCountSC))
512541 return false;
513542
514 BasicBlock *Header = L->getHeader();
515543 BasicBlock *PreHeader = L->getLoopPreheader();
516544 BranchInst *PreHeaderBR = cast(PreHeader->getTerminator());
517545 const DataLayout &DL = Header->getModule()->getDataLayout();
653681 // iterations. This function adds the appropriate CFG connections.
654682 BasicBlock *InsertBot = UseEpilogRemainder ? LatchExit : PrologExit;
655683 BasicBlock *InsertTop = UseEpilogRemainder ? EpilogPreHeader : PrologPreHeader;
656 CloneLoopBlocks(L, ModVal, CreateRemainderLoop, UseEpilogRemainder, InsertTop,
657 InsertBot, NewPreHeader, NewBlocks, LoopBlocks, VMap, DT, LI);
684 Loop *remainderLoop = CloneLoopBlocks(
685 L, ModVal, CreateRemainderLoop, UseEpilogRemainder, InsertTop, InsertBot,
686 NewPreHeader, NewBlocks, LoopBlocks, VMap, DT, LI);
658687
659688 // Insert the cloned blocks into the function.
660689 F->getBasicBlockList().splice(InsertBot->getIterator(),
661690 F->getBasicBlockList(),
662691 NewBlocks[0]->getIterator(),
663692 F->end());
693
694 // Now the loop blocks are cloned and the other exiting blocks from the
695 // remainder are connected to the original Loop's exit blocks. The remaining
696 // work is to update the phi nodes in the original loop, and take in the
697 // values from the cloned region. Also update the dominator info for
698 // OtherExits, since we have new edges into OtherExits.
699 for (auto *BB : OtherExits) {
700 for (auto &II : *BB) {
701
702 // Given we preserve LCSSA form, we know that the values used outside the
703 // loop will be used through these phi nodes at the exit blocks that are
704 // transformed below.
705 if (!isa(II))
706 break;
707 PHINode *Phi = cast(&II);
708 unsigned oldNumOperands = Phi->getNumIncomingValues();
709 // Add the incoming values from the remainder code to the end of the phi
710 // node.
711 for (unsigned i =0; i < oldNumOperands; i++){
712 Value *newVal = VMap[Phi->getIncomingValue(i)];
713 if (!newVal) {
714 assert(isa(Phi->getIncomingValue(i)) &&
715 "VMap should exist for all values except constants!");
716 newVal = Phi->getIncomingValue(i);
717 }
718 Phi->addIncoming(newVal,
719 cast(VMap[Phi->getIncomingBlock(i)]));
720 }
721 }
722 // Update the dominator info because the immediate dominator is no longer the
723 // header of the original Loop. BB has edges both from L and remainder code.
724 // Since the preheader determines which loop is run (L or directly jump to
725 // the remainder code), we set the immediate dominator as the preheader.
726 if (DT)
727 DT->changeImmediateDominator(BB, PreHeader);
728 }
664729
665730 // Loop structure should be the following:
666731 // Epilog Prolog
724789 if (Loop *ParentLoop = L->getParentLoop())
725790 SE->forgetLoop(ParentLoop);
726791
792 // Canonicalize to LoopSimplifyForm both original and remainder loops. We
793 // cannot rely on the LoopUnrollPass to do this because it only does
794 // canonicalization for parent/subloops and not the sibling loops.
795 if (OtherExits.size() > 0) {
796 // Generate dedicated exit blocks for the original loop, to preserve
797 // LoopSimplifyForm.
798 formDedicatedExitBlocks(L, DT, LI, PreserveLCSSA);
799 // Generate dedicated exit blocks for the remainder loop if one exists, to
800 // preserve LoopSimplifyForm.
801 if (remainderLoop)
802 formDedicatedExitBlocks(remainderLoop, DT, LI, PreserveLCSSA);
803 }
804
727805 NumRuntimeUnrolled++;
728806 return true;
729807 }
0 ; RUN: opt < %s -loop-unroll -unroll-runtime=true -unroll-runtime-epilog=true -unroll-runtime-multi-exit=true -verify-dom-info -verify-loop-info -instcombine -S| FileCheck %s
1 ; RUN: opt < %s -loop-unroll -unroll-runtime -unroll-count=2 -unroll-runtime-epilog=true -unroll-runtime-multi-exit=true -verify-dom-info -verify-loop-info -instcombine
2
3 ; the second RUN generates an epilog remainder block for all the test
4 ; cases below (it does not generate a loop).
5
6 ; test with three exiting and three exit blocks.
7 ; none of the exit blocks have successors
8 define void @test1(i64 %trip, i1 %cond) {
9 ; CHECK-LABEL: test1
10 ; CHECK-NEXT: entry:
11 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1
12 ; CHECK-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7
13 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7
14 ; CHECK-NEXT: br i1 [[TMP1]], label %exit2.loopexit.unr-lcssa, label [[ENTRY_NEW:%.*]]
15 ; CHECK: entry.new:
16 ; CHECK-NEXT: [[UNROLL_ITER:%.*]] = sub i64 [[TRIP]], [[XTRAITER]]
17 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
18 ; CHECK-LABEL: loop_latch.epil:
19 ; CHECK-NEXT: %epil.iter.sub = add i64 %epil.iter, -1
20 ; CHECK-NEXT: %epil.iter.cmp = icmp eq i64 %epil.iter.sub, 0
21 ; CHECK-NEXT: br i1 %epil.iter.cmp, label %exit2.loopexit.epilog-lcssa, label %loop_header.epil
22 ; CHECK-LABEL: loop_latch.7:
23 ; CHECK-NEXT: %niter.nsub.7 = add i64 %niter, -8
24 ; CHECK-NEXT: %niter.ncmp.7 = icmp eq i64 %niter.nsub.7, 0
25 ; CHECK-NEXT: br i1 %niter.ncmp.7, label %exit2.loopexit.unr-lcssa.loopexit, label %loop_header
26 entry:
27 br label %loop_header
28
29 loop_header:
30 %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop_latch ]
31 br i1 %cond, label %loop_latch, label %loop_exiting_bb1
32
33 loop_exiting_bb1:
34 br i1 false, label %loop_exiting_bb2, label %exit1
35
36 loop_exiting_bb2:
37 br i1 false, label %loop_latch, label %exit3
38
39 exit3:
40 ret void
41
42 loop_latch:
43 %iv_next = add i64 %iv, 1
44 %cmp = icmp ne i64 %iv_next, %trip
45 br i1 %cmp, label %loop_header, label %exit2.loopexit
46
47 exit1:
48 ret void
49
50 exit2.loopexit:
51 ret void
52 }
53
54
55 ; test with three exiting and two exit blocks.
56 ; The non-latch exit block has 2 unique predecessors.
57 ; There are 2 values passed to the exit blocks that are calculated at every iteration.
58 ; %sum.02 and %add. Both of these are incoming values for phi from every exiting
59 ; unrolled block.
60 define i32 @test2(i32* nocapture %a, i64 %n) {
61 ; CHECK-LABEL: test2
62 ; CHECK-LABEL: for.exit2.loopexit:
63 ; CHECK-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %for.body ], [ 42, %for.exiting_block.1 ], [ %add.1, %for.body.1 ], [ 42, %for.exiting_block.2 ], [ %add.2, %for.body.2 ], [ 42, %for.exiting_block.3 ],
64 ; CHECK-NEXT: br label %for.exit2
65 ; CHECK-LABEL: for.exit2.loopexit2:
66 ; CHECK-NEXT: %retval.ph3 = phi i32 [ 42, %for.exiting_block.epil ], [ %sum.02.epil, %header.epil ]
67 ; CHECK-NEXT: br label %for.exit2
68 ; CHECK-LABEL: for.exit2:
69 ; CHECK-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph3, %for.exit2.loopexit2 ]
70 ; CHECK-NEXT: ret i32 %retval
71 ; CHECK: %niter.nsub.7 = add i64 %niter, -8
72 entry:
73 br label %header
74
75 header:
76 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
77 %sum.02 = phi i32 [ %add, %for.body ], [ 0, %entry ]
78 br i1 false, label %for.exit2, label %for.exiting_block
79
80 for.exiting_block:
81 %cmp = icmp eq i64 %n, 42
82 br i1 %cmp, label %for.exit2, label %for.body
83
84 for.body:
85 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
86 %0 = load i32, i32* %arrayidx, align 4
87 %add = add nsw i32 %0, %sum.02
88 %indvars.iv.next = add i64 %indvars.iv, 1
89 %exitcond = icmp eq i64 %indvars.iv.next, %n
90 br i1 %exitcond, label %for.end, label %header
91
92 for.end: ; preds = %for.body
93 %sum.0.lcssa = phi i32 [ %add, %for.body ]
94 ret i32 %sum.0.lcssa
95
96 for.exit2:
97 %retval = phi i32 [ %sum.02, %header ], [ 42, %for.exiting_block ]
98 ret i32 %retval
99 }
100
101 ; test with two exiting and three exit blocks.
102 ; the non-latch exiting block has a switch.
103 define void @test3(i64 %trip, i64 %add) {
104 ; CHECK-LABEL: test3
105 ; CHECK-NEXT: entry:
106 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1
107 ; CHECK-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7
108 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7
109 ; CHECK-NEXT: br i1 [[TMP1]], label %exit2.loopexit.unr-lcssa, label [[ENTRY_NEW:%.*]]
110 ; CHECK: entry.new:
111 ; CHECK-NEXT: %unroll_iter = sub i64 [[TRIP]], [[XTRAITER]]
112 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
113 ; CHECK-LABEL: loop_header:
114 ; CHECK-NEXT: %sum = phi i64 [ 0, %entry.new ], [ %sum.next.7, %loop_latch.7 ]
115 ; CHECK-NEXT: %niter = phi i64 [ %unroll_iter, %entry.new ], [ %niter.nsub.7, %loop_latch.7 ]
116 ; CHECK-LABEL: loop_exiting_bb1.7:
117 ; CHECK-NEXT: switch i64 %sum.next.6, label %loop_latch.7
118 ; CHECK-LABEL: loop_latch.7:
119 ; CHECK-NEXT: %sum.next.7 = add i64 %sum.next.6, %add
120 ; CHECK-NEXT: %niter.nsub.7 = add i64 %niter, -8
121 ; CHECK-NEXT: %niter.ncmp.7 = icmp eq i64 %niter.nsub.7, 0
122 ; CHECK-NEXT: br i1 %niter.ncmp.7, label %exit2.loopexit.unr-lcssa.loopexit, label %loop_header
123 entry:
124 br label %loop_header
125
126 loop_header:
127 %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop_latch ]
128 %sum = phi i64 [ 0, %entry ], [ %sum.next, %loop_latch ]
129 br i1 undef, label %loop_latch, label %loop_exiting_bb1
130
131 loop_exiting_bb1:
132 switch i64 %sum, label %loop_latch [
133 i64 24, label %exit1
134 i64 42, label %exit3
135 ]
136
137 exit3:
138 ret void
139
140 loop_latch:
141 %iv_next = add nuw nsw i64 %iv, 1
142 %sum.next = add i64 %sum, %add
143 %cmp = icmp ne i64 %iv_next, %trip
144 br i1 %cmp, label %loop_header, label %exit2.loopexit
145
146 exit1:
147 ret void
148
149 exit2.loopexit:
150 ret void
151 }
152
153 ; FIXME: Support multiple exiting blocks to the same latch exit block.
154 define i32 @test4(i32* nocapture %a, i64 %n, i1 %cond) {
155 ; CHECK-LABEL: test4
156 ; CHECK-NOT: .unr
157 ; CHECK-NOT: .epil
158 entry:
159 br label %header
160
161 header:
162 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
163 %sum.02 = phi i32 [ %add, %for.body ], [ 0, %entry ]
164 br i1 %cond, label %for.end, label %for.exiting_block
165
166 for.exiting_block:
167 %cmp = icmp eq i64 %n, 42
168 br i1 %cmp, label %for.exit2, label %for.body
169
170 for.body: ; preds = %for.body, %entry
171 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
172 %0 = load i32, i32* %arrayidx, align 4
173 %add = add nsw i32 %0, %sum.02
174 %indvars.iv.next = add i64 %indvars.iv, 1
175 %exitcond = icmp eq i64 %indvars.iv.next, %n
176 br i1 %exitcond, label %for.end, label %header
177
178 for.end: ; preds = %for.body, %entry
179 %sum.0.lcssa = phi i32 [ 0, %header ], [ %add, %for.body ]
180 ret i32 %sum.0.lcssa
181
182 for.exit2:
183 ret i32 42
184 }
185
186 ; two exiting and two exit blocks.
187 ; the non-latch exiting block has duplicate edges to the non-latch exit block.
188 define i64 @test5(i64 %trip, i64 %add, i1 %cond) {
189 ; CHECK-LABEL: test5
190 ; CHECK-LABEL: exit1.loopexit:
191 ; CHECK-NEXT: %result.ph = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.2, %loop_exiting.2 ],
192 ; CHECK-NEXT: br label %exit1
193 ; CHECK-LABEL: exit1.loopexit2:
194 ; CHECK-NEXT: %ivy.epil = add i64 %iv.epil, %add
195 ; CHECK-NEXT: br label %exit1
196 ; CHECK-LABEL: exit1:
197 ; CHECK-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %ivy.epil, %exit1.loopexit2 ]
198 ; CHECK-NEXT: ret i64 %result
199 ; CHECK-LABEL: loop_latch.7:
200 ; CHECK: %niter.nsub.7 = add i64 %niter, -8
201 entry:
202 br label %loop_header
203
204 loop_header:
205 %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop_latch ]
206 %sum = phi i64 [ 0, %entry ], [ %sum.next, %loop_latch ]
207 br i1 %cond, label %loop_latch, label %loop_exiting
208
209 loop_exiting:
210 %ivy = add i64 %iv, %add
211 switch i64 %sum, label %loop_latch [
212 i64 24, label %exit1
213 i64 42, label %exit1
214 ]
215
216 loop_latch:
217 %iv_next = add nuw nsw i64 %iv, 1
218 %sum.next = add i64 %sum, %add
219 %cmp = icmp ne i64 %iv_next, %trip
220 br i1 %cmp, label %loop_header, label %latchexit
221
222 exit1:
223 %result = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ]
224 ret i64 %result
225
226 latchexit:
227 ret i64 %sum.next
228 }
229
230 ; test when exit blocks have successors.
231 define i32 @test6(i32* nocapture %a, i64 %n, i1 %cond, i32 %x) {
232 ; CHECK-LABEL: test6
233 ; CHECK-LABEL: for.exit2.loopexit:
234 ; CHECK-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %latch ], [ 42, %for.exiting_block.1 ], [ %add.1, %latch.1 ], [ 42, %for.exiting_block.2 ], [ %add.2, %latch.2 ],
235 ; CHECK-NEXT: br label %for.exit2
236 ; CHECK-LABEL: for.exit2.loopexit2:
237 ; CHECK-NEXT: %retval.ph3 = phi i32 [ 42, %for.exiting_block.epil ], [ %sum.02.epil, %header.epil ]
238 ; CHECK-NEXT: br label %for.exit2
239 ; CHECK-LABEL: for.exit2:
240 ; CHECK-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph3, %for.exit2.loopexit2 ]
241 ; CHECK-NEXT: br i1 %cond, label %exit_true, label %exit_false
242 ; CHECK-LABEL: latch.7:
243 ; CHECK: %niter.nsub.7 = add i64 %niter, -8
244 entry:
245 br label %header
246
247 header:
248 %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ]
249 %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ]
250 br i1 false, label %for.exit2, label %for.exiting_block
251
252 for.exiting_block:
253 %cmp = icmp eq i64 %n, 42
254 br i1 %cmp, label %for.exit2, label %latch
255
256 latch:
257 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
258 %load = load i32, i32* %arrayidx, align 4
259 %add = add nsw i32 %load, %sum.02
260 %indvars.iv.next = add i64 %indvars.iv, 1
261 %exitcond = icmp eq i64 %indvars.iv.next, %n
262 br i1 %exitcond, label %latch_exit, label %header
263
264 latch_exit:
265 %sum.0.lcssa = phi i32 [ %add, %latch ]
266 ret i32 %sum.0.lcssa
267
268 for.exit2:
269 %retval = phi i32 [ %sum.02, %header ], [ 42, %for.exiting_block ]
270 %addx = add i32 %retval, %x
271 br i1 %cond, label %exit_true, label %exit_false
272
273 exit_true:
274 ret i32 %retval
275
276 exit_false:
277 ret i32 %addx
278 }