llvm.org GIT mirror llvm / 980c010
[LoopDeletion] Update exits correctly when multiple duplicate edges from an exiting block Summary: Currently, we incorrectly update exit blocks of loops when there are multiple edges from a single exiting block to the exit block. This can happen when we have switches as the terminator of the exiting blocks. The fix here is to correctly update the phi nodes in the exit block, and remove all incoming values *except* for one which is from the preheader. Note: Currently, this error can manifest only while deleting non-executed loops. However, it is possible to trigger this error in invariant loops, once we enhance the logic around the exit conditions for the loop check. Reviewers: chandlerc, dberlin, sanjoy, efriedma Reviewed by: efriedma Subscribers: mzolotukhin, llvm-commits Differential Revision: https://reviews.llvm.org/D34516 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306048 91177308-0d34-0410-b5e6-96231b3b80d8 Anna Thomas 2 years ago
2 changed file(s) with 97 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
226226 auto *ExitBlock = L->getUniqueExitBlock();
227227 assert(ExitBlock && "Should have a unique exit block!");
228228
229 assert(L->hasDedicatedExits() && "Loop should have dedicated exits!");
230
229231 // Connect the preheader directly to the exit block.
230232 // Even when the loop is never executed, we cannot remove the edge from the
231233 // source block to the exit block. Consider the case where the unexecuted loop
235237 // non-loop, it will be deleted in a future iteration of loop deletion pass.
236238 Preheader->getTerminator()->replaceUsesOfWith(L->getHeader(), ExitBlock);
237239
238 SmallVector ExitingBlocks;
239 L->getExitingBlocks(ExitingBlocks);
240240 // Rewrite phis in the exit block to get their inputs from the Preheader
241241 // instead of the exiting block.
242 BasicBlock *ExitingBlock = ExitingBlocks[0];
243242 BasicBlock::iterator BI = ExitBlock->begin();
244243 while (PHINode *P = dyn_cast(BI)) {
245 int j = P->getBasicBlockIndex(ExitingBlock);
246 assert(j >= 0 && "Can't find exiting block in exit block's phi node!");
244 // Set the zero'th element of Phi to be from the preheader and remove all
245 // other incoming values. Given the loop has dedicated exits, all other
246 // incoming values must be from the exiting blocks.
247 int PredIndex = 0;
247248 if (LoopIsNeverExecuted)
248 P->setIncomingValue(j, UndefValue::get(P->getType()));
249 P->setIncomingBlock(j, Preheader);
250 for (unsigned i = 1; i < ExitingBlocks.size(); ++i)
251 P->removeIncomingValue(ExitingBlocks[i]);
249 P->setIncomingValue(PredIndex, UndefValue::get(P->getType()));
250 P->setIncomingBlock(PredIndex, Preheader);
251 // Removes all incoming values from all other exiting blocks (including
252 // duplicate values from an exiting block).
253 // Nuke all entries except the zero'th entry which is the preheader entry.
254 // NOTE! We need to remove Incoming Values in the reverse order as done
255 // below, to keep the indices valid for deletion (removeIncomingValues
256 // updates getNumIncomingValues and shifts all values down into the operand
257 // being deleted).
258 for (unsigned i = 0, e = P->getNumIncomingValues() - 1; i != e; ++i)
259 P->removeIncomingValue(e-i, false);
260
261 assert((P->getNumIncomingValues() == 1 &&
262 P->getIncomingBlock(PredIndex) == Preheader) &&
263 "Should have exactly one value and that's from the preheader!");
252264 ++BI;
253265 }
254266
333333 ret void
334334 }
335335
336
337 ; 2 edges from a single exiting block to the exit block.
338 define i64 @test12(i64 %n){
339 ;CHECK-LABEL: @test12
340 ; CHECK-NOT: L1:
341 ; CHECK-NOT: L1Latch:
342 ; CHECK-LABEL: L1.preheader:
343 ; CHECK-NEXT: br label %exit
344 ; CHECK-LABEL: exit:
345 ; CHECK-NEXT: %y.phi = phi i64 [ undef, %L1.preheader ]
346 ; CHECK-NEXT: ret i64 %y.phi
347
348 entry:
349 br i1 true, label %exit1, label %L1
350
351 exit1:
352 ret i64 42
353
354 L1: ; preds = %L1Latch, %entry
355 %y.next = phi i64 [ 0, %entry ], [ %y.add, %L1Latch ]
356 br i1 true, label %L1Latch, label %exit
357
358 L1Latch: ; preds = %L1
359 %y = phi i64 [ %y.next, %L1 ]
360 %y.add = add i64 %y, %n
361 %cond2 = icmp eq i64 %y.add, 42
362 switch i64 %n, label %L1 [
363 i64 10, label %exit
364 i64 20, label %exit
365 ]
366
367 exit: ; preds = %L1Latch, %L1Latch
368 %y.phi = phi i64 [ 10, %L1Latch ], [ 10, %L1Latch ], [ %y.next, %L1]
369 ret i64 %y.phi
370 }
371
372 ; multiple edges to exit block from the same exiting blocks
373 define i64 @test13(i64 %n) {
374 ; CHECK-LABEL: @test13
375 ; CHECK-NOT: L1:
376 ; CHECK-NOT: L1Latch:
377 ; CHECK-LABEL: L1.preheader:
378 ; CHECK-NEXT: br label %exit
379 ; CHECK-LABEL: exit:
380 ; CHECK-NEXT: %y.phi = phi i64 [ undef, %L1.preheader ]
381 ; CHECK-NEXT: ret i64 %y.phi
382
383 entry:
384 br i1 true, label %exit1, label %L1
385
386 exit1:
387 ret i64 42
388
389 L1: ; preds = %L1Latch, %entry
390 %y.next = phi i64 [ 0, %entry ], [ %y.add, %L1Latch ]
391 br i1 true, label %L1Block, label %exit
392
393 L1Block: ; preds = %L1
394 %y = phi i64 [ %y.next, %L1 ]
395 %y.add = add i64 %y, %n
396 %cond2 = icmp eq i64 %y.add, 42
397 switch i64 %n, label %L1Latch [
398 i64 10, label %exit
399 i64 20, label %exit
400 ]
401
402 L1Latch:
403 switch i64 %n, label %L1 [
404 i64 30, label %exit
405 i64 40, label %exit
406 ]
407
408 exit: ; preds = %L1Block, %L1, %L1Latch
409 %y.phi = phi i64 [ 10, %L1Block ], [ 10, %L1Block ], [ %y.next, %L1 ], [ 30, %L1Latch ], [ 30, %L1Latch ]
410 ret i64 %y.phi
411 }