Skip to content

Commit 71acf8d

Browse files
committed
Fix SimplifyCFG CheckedCastBrJumpThreading.
This pass was rewriting branches using the orignal branch target instead of the new branch target. It used to not matter when the pass was mannually splitting critical edges later. Now the splitting is handled automatically. Fixes rdar://71447520 (SILVerifier error after SimplifyCFG "Instruction does not dominate all uses!")
1 parent 9e4bdb6 commit 71acf8d

File tree

2 files changed

+100
-13
lines changed

2 files changed

+100
-13
lines changed

lib/SILOptimizer/Utils/CheckedCastBrJumpThreading.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -251,13 +251,12 @@ void CheckedCastBrJumpThreading::Edit::modifyCFGForFailurePreds(
251251
assert(!Cloner.wasCloned());
252252
Cloner.cloneBlock();
253253
SILBasicBlock *TargetFailureBB = Cloner.getNewBB();
254-
auto *TI = TargetFailureBB->getTerminator();
255-
SILBuilderWithScope Builder(TI);
256-
// This BB copy branches to a FailureBB.
257-
auto *CCBI = cast<CheckedCastBranchInst>(CCBBlock->getTerminator());
258-
Builder.createBranch(TI->getLoc(), CCBI->getFailureBB());
259-
TI->eraseFromParent();
260-
splitIfCriticalEdge(CCBBlock, CCBI->getFailureBB());
254+
auto *clonedCCBI =
255+
cast<CheckedCastBranchInst>(TargetFailureBB->getTerminator());
256+
SILBuilderWithScope Builder(clonedCCBI);
257+
// This BB copy branches to the FailureBB.
258+
Builder.createBranch(clonedCCBI->getLoc(), clonedCCBI->getFailureBB());
259+
clonedCCBI->eraseFromParent();
261260

262261
// Redirect all FailurePreds to the copy of BB.
263262
for (auto *Pred : FailurePreds) {
@@ -272,9 +271,9 @@ void CheckedCastBrJumpThreading::Edit::modifyCFGForFailurePreds(
272271
/// a landing basic block for all FailurePreds.
273272
void CheckedCastBrJumpThreading::Edit::modifyCFGForSuccessPreds(
274273
BasicBlockCloner &Cloner) {
275-
auto *CCBI = cast<CheckedCastBranchInst>(CCBBlock->getTerminator());
276274

277275
if (InvertSuccess) {
276+
auto *CCBI = cast<CheckedCastBranchInst>(CCBBlock->getTerminator());
278277
SILBuilderWithScope(CCBI).createBranch(CCBI->getLoc(),
279278
CCBI->getFailureBB());
280279
CCBI->eraseFromParent();
@@ -287,13 +286,14 @@ void CheckedCastBrJumpThreading::Edit::modifyCFGForSuccessPreds(
287286
assert(!Cloner.wasCloned());
288287
Cloner.cloneBlock();
289288
SILBasicBlock *TargetSuccessBB = Cloner.getNewBB();
290-
auto *TI = TargetSuccessBB->getTerminator();
291-
SILBuilderWithScope Builder(TI);
289+
auto *clonedCCBI =
290+
cast<CheckedCastBranchInst>(TargetSuccessBB->getTerminator());
291+
SILBuilderWithScope Builder(clonedCCBI);
292292
// This BB copy branches to SuccessBB.
293293
// Take argument value from the dominating BB.
294-
Builder.createBranch(TI->getLoc(), CCBI->getSuccessBB(), {SuccessArg});
295-
TI->eraseFromParent();
296-
splitIfCriticalEdge(CCBBlock, CCBI->getSuccessBB());
294+
Builder.createBranch(clonedCCBI->getLoc(), clonedCCBI->getSuccessBB(),
295+
{SuccessArg});
296+
clonedCCBI->eraseFromParent();
297297

298298
// Redirect all SuccessPreds to the copy of BB.
299299
for (auto *Pred : SuccessPreds) {
@@ -312,6 +312,7 @@ void CheckedCastBrJumpThreading::Edit::modifyCFGForSuccessPreds(
312312

313313
// Add an unconditional jump at the end of the block.
314314
// Take argument value from the dominating BB
315+
auto *CCBI = cast<CheckedCastBranchInst>(CCBBlock->getTerminator());
315316
SILBuilderWithScope(CCBI).createBranch(CCBI->getLoc(), CCBI->getSuccessBB(),
316317
{SuccessArg});
317318
CCBI->eraseFromParent();
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all -simplify-cfg -debug-only=sil-simplify-cfg %s -o /dev/null 2>&1 | %FileCheck %s
2+
3+
// REQUIRES: asserts
4+
5+
import Builtin
6+
import Swift
7+
8+
import Builtin
9+
import Swift
10+
11+
protocol OtherKlass : class {}
12+
13+
class Klass {}
14+
15+
sil @getKlass : $@convention(thin) () -> @owned Klass
16+
17+
// Verify that checked-cast jump-threading kicks in and generates verifiable SIL.
18+
//
19+
// CHECK: Condition is the same if reached over {{.*}} parent @$testCheckCastJumpThread : $@convention(thin) (@guaranteed Klass) -> @owned OtherKlass }
20+
// CHECK-NEXT: bb3(%{{.*}} : $OtherKlass):
21+
// CHECK-NEXT: br bb5(%{{.*}} : $Klass)
22+
sil shared @$testCheckCastJumpThread : $@convention(thin) (@guaranteed Klass) -> @owned OtherKlass {
23+
bb0(%0 : $Klass):
24+
%1 = function_ref @getKlass : $@convention(thin) () -> @owned Klass
25+
%2 = integer_literal $Builtin.Int64, 1
26+
%3 = apply %1() : $@convention(thin) () -> @owned Klass
27+
checked_cast_br %3 : $Klass to OtherKlass, bb1, bb2
28+
29+
bb1(%5 : $OtherKlass):
30+
%6 = integer_literal $Builtin.Int1, -1
31+
br bb3(%6 : $Builtin.Int1)
32+
33+
bb2:
34+
%8 = integer_literal $Builtin.Int1, 0
35+
br bb3(%8 : $Builtin.Int1)
36+
37+
bb3(%10 : $Builtin.Int1):
38+
cond_br %10, bb5, bb6
39+
40+
bb4:
41+
unreachable
42+
43+
bb5:
44+
br bb7(%3 : $Klass)
45+
46+
bb6:
47+
strong_release %3 : $Klass
48+
br bb10(%2 : $Builtin.Int64)
49+
50+
bb7(%16 : $Klass):
51+
checked_cast_br %16 : $Klass to OtherKlass, bb9, bb8
52+
53+
bb8:
54+
strong_release %16 : $Klass
55+
br bb4
56+
57+
bb9(%20 : $OtherKlass):
58+
return %20 : $OtherKlass
59+
60+
bb10(%22 : $Builtin.Int64):
61+
%23 = apply %1() : $@convention(thin) () -> @owned Klass
62+
checked_cast_br %23 : $Klass to OtherKlass, bb11, bb12
63+
64+
bb11(%25 : $OtherKlass):
65+
%26 = integer_literal $Builtin.Int1, -1
66+
br bb13(%26 : $Builtin.Int1)
67+
68+
bb12:
69+
%28 = integer_literal $Builtin.Int1, 0
70+
br bb13(%28 : $Builtin.Int1)
71+
72+
bb13(%30 : $Builtin.Int1):
73+
cond_br %30, bb14, bb15
74+
75+
bb14:
76+
br bb7(%23 : $Klass)
77+
78+
bb15:
79+
cond_br undef, bb16, bb17
80+
81+
bb16:
82+
br bb4
83+
84+
bb17:
85+
br bb10(undef : $Builtin.Int64)
86+
}

0 commit comments

Comments
 (0)