Skip to content

Commit 08eaf82

Browse files
authored
Merge pull request #84680 from tshortli/switch-dispatch-mandatory-optimization-for-custom-availability
SILOptimizer: Fix mandatory switch dispatch elimination for unreachable cases
2 parents 0fbf70e + 270ea8b commit 08eaf82

File tree

2 files changed

+64
-3
lines changed

2 files changed

+64
-3
lines changed

lib/SILOptimizer/Mandatory/DiagnoseUnreachable.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -926,9 +926,7 @@ static bool eliminateSwitchDispatchOnUnavailableElements(
926926
SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 4> NewCaseBBs;
927927
for (unsigned i : range(SWI.getNumCases())) {
928928
auto CaseBB = SWI.getCase(i);
929-
auto availableAtr = CaseBB.first->getUnavailableAttr();
930-
931-
if (availableAtr && availableAtr->isUnconditionallyUnavailable()) {
929+
if (!CaseBB.first->isAvailableDuringLowering()) {
932930
// Mark the basic block as potentially unreachable.
933931
SILBasicBlock *UnreachableBlock = CaseBB.second;
934932
if (!State->PossiblyUnreachableBlocks.contains(UnreachableBlock)) {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// RUN: %target-swift-emit-sil -module-name Test %s -verify -parse-as-library \
2+
// RUN: -enable-experimental-feature CustomAvailability \
3+
// RUN: -define-enabled-availability-domain EnabledDomain \
4+
// RUN: -define-always-enabled-availability-domain AlwaysEnabledDomain \
5+
// RUN: -define-disabled-availability-domain DisabledDomain \
6+
// RUN: -define-dynamic-availability-domain DynamicDomain \
7+
// RUN: -Onone \
8+
// RUN: | %FileCheck %s --check-prefixes=CHECK,CHECK-NOOPT
9+
10+
// REQUIRES: swift_feature_CustomAvailability
11+
12+
public enum Enum {
13+
case alwaysAvailable
14+
15+
@available(*, unavailable)
16+
case alwaysUnavailable
17+
18+
@available(EnabledDomain)
19+
case enabled
20+
21+
@available(EnabledDomain, unavailable)
22+
case enabledUnavailable
23+
24+
@available(AlwaysEnabledDomain)
25+
case alwaysEnabled
26+
27+
@available(AlwaysEnabledDomain, unavailable)
28+
case alwaysEnabledUnavailable
29+
30+
@available(DisabledDomain)
31+
case disabled
32+
33+
@available(DisabledDomain, unavailable)
34+
case disabledUnavailable
35+
36+
@available(DynamicDomain)
37+
case dynamic
38+
39+
@available(DynamicDomain, unavailable)
40+
case dynamicUnavailable
41+
}
42+
43+
// CHECK-LABEL: sil @$s4Test22testFullyCoveredSwitchyyAA4EnumOF : $@convention(thin) (Enum) -> () {
44+
// CHECK: switch_enum %0, case #Enum.alwaysAvailable!enumelt: {{bb[0-9]+}}, case #Enum.alwaysUnavailable!enumelt: {{bb[0-9]+}}, case #Enum.enabled!enumelt: {{bb[0-9]+}}, case #Enum.alwaysEnabled!enumelt: {{bb[0-9]+}}, case #Enum.disabledUnavailable!enumelt: {{bb[0-9]+}}, case #Enum.dynamic!enumelt: {{bb[0-9]+}}, case #Enum.dynamicUnavailable!enumelt: {{bb[0-9]+}}, default [[DEFAULTBB:bb[0-9]+]]
45+
// CHECK: [[DEFAULTBB]]:
46+
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
47+
// CHECK-NEXT: cond_fail {{%.*}}, "unexpected enum value"
48+
// CHECK-NEXT: unreachable
49+
// CHECK: } // end sil function '$s4Test22testFullyCoveredSwitchyyAA4EnumOF'
50+
public func testFullyCoveredSwitch(_ e: Enum) {
51+
switch e {
52+
case .alwaysAvailable: ()
53+
case .alwaysUnavailable: ()
54+
case .enabled: ()
55+
case .enabledUnavailable: ()
56+
case .alwaysEnabled: ()
57+
case .alwaysEnabledUnavailable: ()
58+
case .disabled: ()
59+
case .disabledUnavailable: ()
60+
case .dynamic: ()
61+
case .dynamicUnavailable: ()
62+
}
63+
}

0 commit comments

Comments
 (0)