Skip to content

Commit bf3c6cc

Browse files
authored
Merge pull request #11276 from atrick/fold_checked_cast
2 parents c55e07b + 98be5f1 commit bf3c6cc

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

lib/SILOptimizer/Utils/Local.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,6 +1986,8 @@ simplifyCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *Inst) {
19861986
if (ResultNotUsed) {
19871987
EraseInstAction(Inst);
19881988
Builder.setInsertionPoint(BB);
1989+
if (shouldTakeOnSuccess(Inst->getConsumptionKind()))
1990+
Builder.emitDestroyAddr(Loc, Src);
19891991
auto *NewI = Builder.createBranch(Loc, SuccessBB);
19901992
WillSucceedAction();
19911993
return NewI;

test/SILOptimizer/simplify_cfg.sil

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2901,3 +2901,44 @@ bb6(%14 : $foo):
29012901
%16 = tuple ()
29022902
return %16 : $()
29032903
}
2904+
2905+
protocol Q {}
2906+
2907+
class IsQ : Q {}
2908+
2909+
// checked_cast_br take_* should be replaced by a destroy in case it ever
2910+
// converts a managed object to an unmanaged value. Currently this doesn't
2911+
// happen at the language level because bridge (NSNumber->Int) casts aren't
2912+
// represented with checked_cast_br.
2913+
// ---
2914+
// CHECK-LABEL: sil @test_dead_checked_cast_br : $@convention(thin) (@in IsQ) -> () {
2915+
// CHECK: bb0(%0 : $*IsQ):
2916+
// CHECK: [[Q:%.*]] = alloc_stack $Q
2917+
// CHECK: destroy_addr %0 : $*IsQ
2918+
// CHECK: dealloc_stack [[Q]] : $*Q
2919+
// CHECK: [[R:%.*]] = tuple ()
2920+
// CHECK: return [[R]] : $()
2921+
// CHECK-LABEL: } // end sil function 'test_dead_checked_cast_br'
2922+
sil @test_dead_checked_cast_br : $@convention(thin) (@in IsQ) -> () {
2923+
bb0(%0 : $*IsQ):
2924+
%p = alloc_stack $Q
2925+
checked_cast_addr_br take_always IsQ in %0 : $*IsQ to Q in %p : $*Q, bb1, bb3
2926+
2927+
bb1:
2928+
%m1 = integer_literal $Builtin.Int1, -1
2929+
br bb2(%m1 : $Builtin.Int1)
2930+
2931+
bb2(%5 : $Builtin.Int1):
2932+
// To avoid violating ownership, Q needs to be destroyed here. However, that
2933+
// would create a use of the checked_cast, defeating the test. In theory, Q
2934+
// could be some unmananged type with no destroy, but we don't have a way to
2935+
// express that in the type system, and bridged casts don't yet go through
2936+
// this optimization path.
2937+
dealloc_stack %p : $*Q
2938+
%r = tuple ()
2939+
return %r : $()
2940+
2941+
bb3:
2942+
%z = integer_literal $Builtin.Int1, 0
2943+
br bb2(%z : $Builtin.Int1)
2944+
}

0 commit comments

Comments
 (0)