llvm.org GIT mirror llvm / b0a5721
Fix loop unswitching's assumption that a code path which either infinite loops or exits will eventually exit. This fixes PR5373. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112745 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 9 years ago
2 changed file(s) with 61 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
276276 return Changed;
277277 }
278278
279 /// isTrivialLoopExitBlock - Check to see if all paths from BB either:
280 /// 1. Exit the loop with no side effects.
281 /// 2. Branch to the latch block with no side-effects.
279 /// isTrivialLoopExitBlock - Check to see if all paths from BB exit the
280 /// loop with no side effects (including infinite loops).
282281 ///
283 /// If these conditions are true, we return true and set ExitBB to the block we
282 /// If true, we return true and set ExitBB to the block we
284283 /// exit through.
285284 ///
286285 static bool isTrivialLoopExitBlockHelper(Loop *L, BasicBlock *BB,
287286 BasicBlock *&ExitBB,
288287 std::set &Visited) {
289288 if (!Visited.insert(BB).second) {
290 // Already visited and Ok, end of recursion.
291 return true;
289 // Already visited. Without more analysis, this could indicate an infinte loop.
290 return false;
292291 } else if (!L->contains(BB)) {
293292 // Otherwise, this is a loop exit, this is fine so long as this is the
294293 // first exit.
318317 /// process. If so, return the block that is exited to, otherwise return null.
319318 static BasicBlock *isTrivialLoopExitBlock(Loop *L, BasicBlock *BB) {
320319 std::set Visited;
321 Visited.insert(L->getHeader()); // Branches to header are ok.
320 Visited.insert(L->getHeader()); // Branches to header make infinite loops.
322321 BasicBlock *ExitBB = 0;
323322 if (isTrivialLoopExitBlockHelper(L, BB, ExitBB, Visited))
324323 return ExitBB;
350349 if (!BI->isConditional() || BI->getCondition() != Cond)
351350 return false;
352351
353 // Check to see if a successor of the branch is guaranteed to go to the
354 // latch block or exit through a one exit block without having any
352 // Check to see if a successor of the branch is guaranteed to
353 // exit through a unique exit block without having any
355354 // side-effects. If so, determine the value of Cond that causes it to do
356355 // this.
357356 if ((LoopExitBB = isTrivialLoopExitBlock(currentLoop,
0 ; RUN: opt -loop-unswitch -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s
1 ; RUN: opt -loop-unswitch -simplifycfg -S < %s | FileCheck %s
2 ; PR5373
3
4 ; Loop unswitching shouldn't trivially unswitch the true case of condition %a
5 ; in the code here because it leads to an infinite loop. While this doesn't
6 ; contain any instructions with side effects, it's still a kind of side effect.
7 ; It can trivially unswitch on the false cas of condition %a though.
8
9 ; STATS: 2 loop-unswitch - Number of branches unswitched
10 ; STATS: 1 loop-unswitch - Number of unswitches that are trivial
11
12 ; CHECK: @func_16
13 ; CHECK-NEXT: entry:
14 ; CHECK-NEXT: br i1 %a, label %entry.split, label %abort0.split
15
16 ; CHECK: entry.split:
17 ; CHECK-NEXT: br i1 %b, label %cond.end.us, label %abort1
18
19 ; CHECK: cond.end.us:
20 ; CHECK-NEXT: br label %cond.end.us
21
22 ; CHECK: abort0.split:
23 ; CHECK-NEXT: call void @end0() noreturn nounwind
24 ; CHECK-NEXT: unreachable
25
26 ; CHECK: abort1:
27 ; CHECK-NEXT: call void @end1() noreturn nounwind
28 ; CHECK-NEXT: unreachable
29
30 ; CHECK: }
31
32 define void @func_16(i1 %a, i1 %b) nounwind {
33 entry:
34 br label %for.body
35
36 for.body:
37 br i1 %a, label %cond.end, label %abort0
38
39 cond.end:
40 br i1 %b, label %for.body, label %abort1
41
42 abort0:
43 call void @end0() noreturn nounwind
44 unreachable
45
46 abort1:
47 call void @end1() noreturn nounwind
48 unreachable
49 }
50
51 declare void @end0() noreturn
52 declare void @end1() noreturn