Skip to content

Commit d9826f6

Browse files
committed
SimplifyBranch: don't leave an empty block after merging two basic blocks
Although empty blocks are cleaned up at the end of every Simplification pass, it's not legal SIL to have empty blocks and subsequent simplification passes may crash because of this. rdar://115169880
1 parent 44298e1 commit d9826f6

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBranch.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ private extension BranchInst {
7070
}
7171
parentBB.moveAllInstructions(toBeginOf: targetBB, context)
7272
parentBB.moveAllArguments(to: targetBB, context)
73+
context.erase(block: parentBB)
7374
} else {
7475
targetBB.moveAllInstructions(toEndOf: parentBB, context)
76+
context.erase(block: targetBB)
7577
}
7678
}
7779
}

SwiftCompilerSources/Sources/Optimizer/PassManager/Context.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ extension MutatingContext {
7171
erase(instruction: inst)
7272
}
7373

74+
func erase(block: BasicBlock) {
75+
_bridged.eraseBlock(block.bridged)
76+
}
77+
7478
func tryOptimizeApplyOfPartialApply(closure: PartialApplyInst) -> Bool {
7579
if _bridged.tryOptimizeApplyOfPartialApply(closure.bridged) {
7680
notifyInstructionsChanged()
@@ -227,10 +231,6 @@ struct FunctionPassContext : MutatingContext {
227231
}
228232
}
229233

230-
func erase(block: BasicBlock) {
231-
_bridged.eraseBlock(block.bridged)
232-
}
233-
234234
func modifyEffects(in function: Function, _ body: (inout FunctionEffects) -> ()) {
235235
notifyEffectsChanged()
236236
function._modifyEffects(body)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-opt-pass-count=1.1 -simplification -simplify-instruction=br | %FileCheck %s
2+
3+
// REQUIRES: swift_in_compiler
4+
5+
import Swift
6+
import Builtin
7+
8+
// Check that branch simplification doesn't leave empty blocks.
9+
// -sil-opt-pass-count=1.1 prevents dead block elimination which would hide the problem.
10+
11+
12+
13+
// CHECK-LABEL: sil @dont_leave_empty_blocks
14+
// CHECK: bb0(%0 : $Builtin.Int64):
15+
// CHECK-NEXT: br bb1
16+
// CHECK: bb1:
17+
// CHECK-NEXT: return %0
18+
// CHECK: } // end sil function 'dont_leave_empty_blocks'
19+
sil @dont_leave_empty_blocks : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 {
20+
bb0(%0 : $Builtin.Int64):
21+
br bb1
22+
23+
bb1:
24+
br bb2
25+
26+
bb2:
27+
return %0 : $Builtin.Int64
28+
}

0 commit comments

Comments
 (0)