Skip to content

Commit

Permalink
[SimplifyCFG] Correctly test for unconditional branches in GetCaseRes…
Browse files Browse the repository at this point in the history
…ults

GetCaseResults assumed that a terminator with one successor was an
unconditional branch.  This is not necessarily the case, it could be a
cleanupret.

Strengthen the check by querying whether or not the terminator is
exceptional.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283517 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
majnemer committed Oct 7, 2016
1 parent 28b12d7 commit 433ffa6
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/Transforms/Utils/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4503,7 +4503,7 @@ GetCaseResults(SwitchInst *SI, ConstantInt *CaseVal, BasicBlock *CaseDest,
++I) {
if (TerminatorInst *T = dyn_cast<TerminatorInst>(I)) {
// If the terminator is a simple branch, continue to the next block.
if (T->getNumSuccessors() != 1)
if (T->getNumSuccessors() != 1 || T->isExceptional())
return false;
Pred = CaseDest;
CaseDest = T->getSuccessor(0);
Expand Down
60 changes: 60 additions & 0 deletions test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1334,3 +1334,63 @@ cleanup4:
br label %while.body
}

declare void @throw(i1)

define void @wineh_test(i64 %val) personality i32 (...)* @__CxxFrameHandler3 {
entry:
invoke void @throw(i1 false)
to label %unreachable unwind label %cleanup1

unreachable:
unreachable

cleanup1:
%cleanuppad1 = cleanuppad within none []
switch i64 %val, label %cleanupdone2 [
i64 0, label %cleanupdone1
i64 1, label %cleanupdone1
i64 6, label %cleanupdone1
]

cleanupdone1:
cleanupret from %cleanuppad1 unwind label %cleanup2

cleanupdone2:
cleanupret from %cleanuppad1 unwind label %cleanup2

cleanup2:
%phi = phi i1 [ true, %cleanupdone1 ], [ false, %cleanupdone2 ]
%cleanuppad2 = cleanuppad within none []
call void @throw(i1 %phi) [ "funclet"(token %cleanuppad2) ]
unreachable
}

; CHECK-LABEL: @wineh_test(
; CHECK: entry:
; CHECK: invoke void @throw(i1 false)
; CHECK: to label %[[unreachable:.*]] unwind label %[[cleanup1:.*]]

; CHECK: [[unreachable]]:
; CHECK: unreachable

; CHECK: [[cleanup1]]:
; CHECK: %[[cleanuppad1:.*]] = cleanuppad within none []
; CHECK: switch i64 %val, label %[[cleanupdone2:.*]] [
; CHECK: i64 0, label %[[cleanupdone1:.*]]
; CHECK: i64 1, label %[[cleanupdone1]]
; CHECK: i64 6, label %[[cleanupdone1]]
; CHECK: ]

; CHECK: [[cleanupdone1]]:
; CHECK: cleanupret from %[[cleanuppad1]] unwind label %[[cleanup2:.*]]

; CHECK: [[cleanupdone2]]:
; CHECK: cleanupret from %[[cleanuppad1]] unwind label %[[cleanup2]]

; CHECK: [[cleanup2]]:
; CHECK: %[[phi:.*]] = phi i1 [ true, %[[cleanupdone1]] ], [ false, %[[cleanupdone2]] ]
; CHECK: %[[cleanuppad2:.*]] = cleanuppad within none []
; CHECK: call void @throw(i1 %[[phi]]) [ "funclet"(token %[[cleanuppad2]]) ]
; CHECK: unreachable

declare i32 @__CxxFrameHandler3(...)

0 comments on commit 433ffa6

Please sign in to comment.