Skip to content

Commit 106dc8a

Browse files
committed
Fix simplifySwitchEnumUnreachableBlocks for default cases in ossa
Unlike non-ossa, ossa's switch_enum accepts an argument for the default case When all other cases are unreachable, replace the default block's phi with the switch_enum's operand and transform the switch_enum to a branch. Fixes rdar://139441002
1 parent 69571db commit 106dc8a

File tree

3 files changed

+59
-11
lines changed

3 files changed

+59
-11
lines changed

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

+18-11
Original file line numberDiff line numberDiff line change
@@ -1790,9 +1790,7 @@ bool SimplifyCFG::simplifySwitchEnumUnreachableBlocks(SwitchEnumInst *SEI) {
17901790
return true;
17911791
}
17921792

1793-
if (!Element || !Element->hasAssociatedValues() || Dest->args_empty()) {
1794-
assert(Dest->args_empty() && "Unexpected argument at destination!");
1795-
1793+
if (Dest->args_empty()) {
17961794
SILBuilderWithScope(SEI).createBranch(SEI->getLoc(), Dest);
17971795

17981796
addToWorklist(SEI->getParent());
@@ -1802,16 +1800,25 @@ bool SimplifyCFG::simplifySwitchEnumUnreachableBlocks(SwitchEnumInst *SEI) {
18021800
return true;
18031801
}
18041802

1805-
auto &Mod = SEI->getModule();
1806-
auto OpndTy = SEI->getOperand()->getType();
1807-
auto Ty = OpndTy.getEnumElementType(
1808-
Element, Mod, TypeExpansionContext(*SEI->getFunction()));
1809-
auto *UED = SILBuilderWithScope(SEI)
1810-
.createUncheckedEnumData(SEI->getLoc(), SEI->getOperand(), Element, Ty);
1811-
1803+
// If the Dest has an argument, it's case should have an associated value or
1804+
// it is the default case in ossa.
1805+
assert((Element && Element->hasAssociatedValues()) ||
1806+
(SEI->getFunction()->hasOwnership() && SEI->hasDefault() &&
1807+
Dest == SEI->getDefaultBB()));
1808+
SILValue newValue;
1809+
if (SEI->getFunction()->hasOwnership() && SEI->hasDefault() &&
1810+
Dest == SEI->getDefaultBB()) {
1811+
newValue = SEI->getOperand();
1812+
} else {
1813+
auto OpndTy = SEI->getOperand()->getType();
1814+
auto Ty = OpndTy.getEnumElementType(
1815+
Element, SEI->getModule(), TypeExpansionContext(*SEI->getFunction()));
1816+
newValue = SILBuilderWithScope(SEI).createUncheckedEnumData(
1817+
SEI->getLoc(), SEI->getOperand(), Element, Ty);
1818+
}
18121819
assert(Dest->args_size() == 1 && "Expected only one argument!");
18131820
auto *DestArg = Dest->getArgument(0);
1814-
DestArg->replaceAllUsesWith(UED);
1821+
DestArg->replaceAllUsesWith(newValue);
18151822
Dest->eraseArgument(0);
18161823

18171824
SILBuilderWithScope(SEI).createBranch(SEI->getLoc(), Dest);

test/SILOptimizer/simplify_cfg.sil

+21
Original file line numberDiff line numberDiff line change
@@ -3259,3 +3259,24 @@ bb21:
32593259
%75 = tuple ()
32603260
return %75 : $()
32613261
}
3262+
3263+
// CHECK-LABEL: sil @simplify_switch_enum_unreachable :
3264+
// CHECK-NOT: switch_enum
3265+
// CHECK: } // end sil function 'simplify_switch_enum_unreachable'
3266+
sil @simplify_switch_enum_unreachable : $@convention(thin) (@owned Optional<String>) -> () {
3267+
bb0(%0 : $Optional<String>):
3268+
switch_enum %0 : $Optional<String>, case #Optional.some!enumelt: bb5, case #Optional.none!enumelt: bb4
3269+
3270+
bb4:
3271+
unreachable
3272+
3273+
bb5:
3274+
%1 = unchecked_enum_data %0 : $Optional<String>, #Optional.some!enumelt
3275+
release_value %1 : $String
3276+
br bb6
3277+
3278+
bb6:
3279+
%17 = tuple ()
3280+
return %17 : $()
3281+
}
3282+

test/SILOptimizer/simplify_cfg_ossa.sil

+20
Original file line numberDiff line numberDiff line change
@@ -1919,3 +1919,23 @@ bb6:
19191919
%17 = tuple ()
19201920
return %17 : $()
19211921
}
1922+
1923+
// CHECK-LABEL: sil [ossa] @simplify_switch_enum_unreachable :
1924+
// CHECK-NOT: switch_enum
1925+
// CHECK: } // end sil function 'simplify_switch_enum_unreachable'
1926+
sil [ossa] @simplify_switch_enum_unreachable : $@convention(thin) (A) -> () {
1927+
bb0(%0 : $A):
1928+
switch_enum %0 : $A, case #A.B!enumelt: bb1, default bb2
1929+
1930+
bb1:
1931+
unreachable
1932+
1933+
bb2(%defaultArg : $A):
1934+
apply undef(%defaultArg) : $@convention(thin) (A) -> ()
1935+
br bb3
1936+
1937+
bb3:
1938+
%t = tuple ()
1939+
return %t : $()
1940+
}
1941+

0 commit comments

Comments
 (0)