llvm.org GIT mirror llvm / 08bf51e
[LowerSwitch] Fixed faulty PHI node update Summary: When lowerswitch merge several cases into a new default block it's not updating the PHI nodes accordingly. The code that update the PHI nodes for the default edge only update the first entry and do not remove the remaining ones, to make sure the number of entries match the number of predecessors. This is easily fixed by replacing the code that update the PHI node with the already existing utility function for updating PHI nodes. Reviewers: hans, reames, arsenm Reviewed By: arsenm Subscribers: wdng, llvm-commits Differential Revision: https://reviews.llvm.org/D47055 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332960 91177308-0d34-0410-b5e6-96231b3b80d8 Karl-Johan Karlsson 1 year, 5 months ago
2 changed file(s) with 66 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
511511 }
512512 }
513513
514 unsigned NrOfDefaults = (SI->getDefaultDest() == Default) ? 1 : 0;
515 for (const auto &Case : SI->cases())
516 if (Case.getCaseSuccessor() == Default)
517 NrOfDefaults++;
518
514519 // Create a new, empty default block so that the new hierarchy of
515520 // if-then statements go to this and the PHI nodes are happy.
516521 BasicBlock *NewDefault = BasicBlock::Create(SI->getContext(), "NewDefault");
517522 F->getBasicBlockList().insert(Default->getIterator(), NewDefault);
518523 BranchInst::Create(Default, NewDefault);
519524
520 // If there is an entry in any PHI nodes for the default edge, make sure
521 // to update them as well.
522 for (BasicBlock::iterator I = Default->begin(); isa(I); ++I) {
523 PHINode *PN = cast(I);
524 int BlockIdx = PN->getBasicBlockIndex(OrigBlock);
525 assert(BlockIdx != -1 && "Switch didn't go to this successor??");
526 PN->setIncomingBlock((unsigned)BlockIdx, NewDefault);
527 }
528
529525 BasicBlock *SwitchBlock =
530526 switchConvert(Cases.begin(), Cases.end(), LowerBound, UpperBound, Val,
531527 OrigBlock, OrigBlock, NewDefault, UnreachableRanges);
532528
529 // If there are entries in any PHI nodes for the default edge, make sure
530 // to update them as well.
531 fixPhis(Default, OrigBlock, NewDefault, NrOfDefaults);
532
533533 // Branch to our shiny new if-then stuff...
534534 BranchInst::Create(SwitchBlock, OrigBlock);
535535
22 ; Test that we don't crash and have a different basic block for each incoming edge.
33 define void @test0() {
44 ; CHECK-LABEL: @test0
5 ; CHECK: %merge = phi i64 [ 1, %BB3 ], [ 0, %NewDefault ], [ 0, %NodeBlock5 ], [ 0, %LeafBlock1 ]
5 ; CHECK: %merge = phi i64 [ 1, %BB3 ], [ 0, %NodeBlock5 ], [ 0, %LeafBlock1 ], [ 0, %NewDefault ]
66 BB1:
77 switch i32 undef, label %BB2 [
88 i32 3, label %BB2
185185 ._crit_edge: ; preds = %34, %0
186186 ret void
187187 }
188
189 ; Test that the PHI node in for.cond should have one entry for each predecessor
190 ; of its parent basic block after lowerswitch merged several cases into a new
191 ; default block.
192 define void @test3() {
193 ; CHECK-LABEL: @test3
194 entry:
195 br label %lbl1
196
197 lbl1: ; preds = %cleanup, %entry
198 br label %lbl2
199
200 lbl2: ; preds = %cleanup, %lbl1
201 br label %for.cond
202
203 for.cond: ; preds = %cleanup, %cleanup, %lbl2
204 ; CHECK: for.cond:
205 ; CHECK: phi i16 [ undef, %lbl2 ], [ %b.3, %NewDefault ]{{$}}
206 ; CHECK: for.cond1:
207 %b.2 = phi i16 [ undef, %lbl2 ], [ %b.3, %cleanup ], [ %b.3, %cleanup ]
208 br label %for.cond1
209
210 for.cond1: ; preds = %for.inc, %for.cond
211 %b.3 = phi i16 [ %b.2, %for.cond ], [ undef, %for.inc ]
212 %tobool = icmp ne i16 %b.3, 0
213 br i1 %tobool, label %for.body, label %for.end
214
215 for.body: ; preds = %for.cond1
216 br i1 undef, label %if.then, label %for.inc
217
218 if.then: ; preds = %for.body
219 br label %cleanup
220
221 for.inc: ; preds = %for.body
222 br label %for.cond1
223
224 for.end: ; preds = %for.cond1
225 br i1 undef, label %if.then4, label %for.body7
226
227 if.then4: ; preds = %for.end
228 br label %cleanup
229
230 for.body7: ; preds = %for.end
231 br label %cleanup
232
233 cleanup: ; preds = %for.body7, %if.then4, %if.then
234 switch i32 undef, label %unreachable [
235 i32 0, label %for.cond
236 i32 2, label %lbl1
237 i32 5, label %for.cond
238 i32 3, label %lbl2
239 ]
240
241 unreachable: ; preds = %cleanup
242 unreachable
243 }