Skip to content

Commit d6586d9

Browse files
committed
SimplifyCFG: We can't duplicate blocks that contain 'throw'
SR-4404 rdar://31328081
1 parent 268cbba commit d6586d9

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

lib/SIL/LoopInfo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ bool SILLoop::canDuplicate(SILInstruction *I) const {
7676
return false;
7777
}
7878

79+
if (isa<ThrowInst>(I))
80+
return false;
81+
7982
assert(I->isTriviallyDuplicatable() &&
8083
"Code here must match isTriviallyDuplicatable in SILInstruction");
8184
return true;

lib/SIL/SILInstruction.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,9 @@ SILInstruction *SILInstruction::clone(SILInstruction *InsertPt) {
992992
/// additional handling. It is important to know this information when
993993
/// you perform such optimizations like e.g. jump-threading.
994994
bool SILInstruction::isTriviallyDuplicatable() const {
995+
if (isa<ThrowInst>(this))
996+
return false;
997+
995998
if (isa<AllocStackInst>(this) || isa<DeallocStackInst>(this)) {
996999
return false;
9971000
}

test/SILOptimizer/simplify_cfg.sil

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2707,3 +2707,66 @@ bb6:
27072707
return %6 : $()
27082708
}
27092709

2710+
enum TestEnum {
2711+
case int64(Builtin.Int64)
2712+
case string (Base)
2713+
case none
2714+
}
2715+
2716+
enum MyError : Error {
2717+
case a
2718+
case b
2719+
case c(TestEnum)
2720+
}
2721+
2722+
enum MyError2 : Error {
2723+
case o(Optional<MyError>)
2724+
}
2725+
2726+
sil @foo : $@convention(thin) (Builtin.Int64) -> Builtin.Int8
2727+
sil @foo2 : $@convention(thin) (Builtin.Int32) -> Builtin.Int8
2728+
2729+
sil @dont_thread_throw_block : $@convention(thin) (@guaranteed TestEnum) -> (Builtin.Int8, @error Error) {
2730+
bb0(%0 : $TestEnum):
2731+
switch_enum %0 : $TestEnum, case #TestEnum.int64!enumelt.1: bb1, default bb4
2732+
2733+
bb1(%5 : $Builtin.Int64):
2734+
%7 = function_ref @foo : $@convention(thin) (Builtin.Int64) -> Builtin.Int8
2735+
%9 = apply %7(%5) : $@convention(thin) (Builtin.Int64) -> Builtin.Int8
2736+
br bb6(%9 : $Builtin.Int8)
2737+
2738+
bb2(%11 : $Builtin.Int32):
2739+
%13 = function_ref @foo2 : $@convention(thin) (Builtin.Int32) -> Builtin.Int8
2740+
%15 = apply %13(%11) : $@convention(thin) (Builtin.Int32) -> Builtin.Int8
2741+
br bb6(%15 : $Builtin.Int8)
2742+
2743+
bb4:
2744+
%60 = debug_value %0 : $TestEnum
2745+
%22 = alloc_existential_box $Error, $MyError2
2746+
%23 = project_existential_box $MyError2 in %22 : $Error
2747+
switch_enum %0 : $TestEnum, case #TestEnum.none!enumelt: bbnone, case #TestEnum.int64!enumelt.1: bb7, case #TestEnum.string!enumelt.1: bb10
2748+
2749+
bbnone:
2750+
%tn = enum $TestEnum, #TestEnum.none!enumelt
2751+
%en = enum $MyError, #MyError.c!enumelt.1, %tn : $TestEnum
2752+
br bb5(%en : $MyError)
2753+
2754+
bb7(%50 : $Builtin.Int64):
2755+
%t = enum $TestEnum, #TestEnum.int64!enumelt.1, %50 : $Builtin.Int64
2756+
%e1 = enum $MyError, #MyError.c!enumelt.1, %t : $TestEnum
2757+
br bb5(%e1 : $MyError)
2758+
2759+
bb10(%53 : $Base):
2760+
%t4 = enum $TestEnum, #TestEnum.string!enumelt.1, %53 : $Base
2761+
%e4 = enum $MyError, #MyError.c!enumelt.1, %t4 : $TestEnum
2762+
br bb5(%e4 : $MyError)
2763+
2764+
bb5(%e : $MyError):
2765+
%89 = enum $Optional<MyError>, #Optional.some!enumelt.1, %e : $MyError
2766+
%e5 = enum $MyError2, #MyError2.o!enumelt.1, %89 : $Optional<MyError>
2767+
store %e5 to %23 : $*MyError2
2768+
throw %22 : $Error
2769+
2770+
bb6(%44 : $Builtin.Int8):
2771+
return %44 : $Builtin.Int8
2772+
}

0 commit comments

Comments
 (0)