Skip to content

Commit c69184e

Browse files
Merge pull request #61950 from nate-chandler/opaque-values/1/20221105
[AddressLowering] Handle multidefault switch_enum.
2 parents ae631dc + a8dc311 commit c69184e

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3011,7 +3011,7 @@ void UseRewriter::visitSwitchEnumInst(SwitchEnumInst * switchEnum) {
30113011
return;
30123012

30133013
assert(caseBB->getArguments().size() == 1);
3014-
SILArgument *caseArg = caseBB->getArguments()[0];
3014+
SILArgument *caseArg = caseBB->getArgument(0);
30153015

30163016
assert(&switchEnum->getOperandRef(0) == getReusedStorageOperand(caseArg));
30173017
assert(caseDecl->hasAssociatedValues() && "caseBB has a payload argument");
@@ -3053,6 +3053,20 @@ void UseRewriter::visitSwitchEnumInst(SwitchEnumInst * switchEnum) {
30533053
defaultCounter = switchEnum->getDefaultCount();
30543054
if (auto defaultDecl = switchEnum->getUniqueCaseForDefault()) {
30553055
rewriteCase(defaultDecl.get(), defaultBB);
3056+
} else {
3057+
assert(defaultBB->getArguments().size() == 1);
3058+
SILArgument *arg = defaultBB->getArgument(0);
3059+
assert(arg->getType().isAddressOnly(*pass.function));
3060+
auto builder = pass.getBuilder(defaultBB->begin());
3061+
auto addr = enumAddr;
3062+
auto *load = builder.createTrivialLoadOr(switchEnum->getLoc(), addr,
3063+
LoadOwnershipQualifier::Take);
3064+
// Remap arg to the new dummy load which will be deleted during
3065+
// deleteRewrittenInstructions.
3066+
arg->replaceAllUsesWith(load);
3067+
pass.valueStorageMap.replaceValue(arg, load);
3068+
markRewritten(load, addr);
3069+
defaultBB->eraseArgument(0);
30563070
}
30573071
}
30583072
auto builder = pass.getTermBuilder(switchEnum);

test/SILOptimizer/address_lowering.sil

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,24 @@ bb4:
11301130
return %31 : $()
11311131
}
11321132

1133+
// Verify the handling of non-unique default case blocks when there is more
1134+
// than one case handled by default.
1135+
// CHECK-LABEL: sil [ossa] @f221_testSwitchDefault : $@convention(thin) <T> (@in Optional<T>) -> () {
1136+
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : $*Optional<T>):
1137+
// CHECK: switch_enum_addr [[INSTANCE]] : $*Optional<T>, default [[EXIT:bb[0-9]+]]
1138+
// CHECK: [[EXIT]]:
1139+
// CHECK: destroy_addr [[INSTANCE]] : $*Optional<T>
1140+
// CHECK-LABEL: } // end sil function 'f221_testSwitchDefault'
1141+
sil [ossa] @f221_testSwitchDefault : $@convention(thin) <T> (@in Optional<T>) -> () {
1142+
entry(%instance : @owned $Optional<T>):
1143+
switch_enum %instance : $Optional<T>, default exit
1144+
1145+
exit(%instance_2 : @owned $Optional<T>):
1146+
destroy_value %instance_2 : $Optional<T>
1147+
%retval = tuple ()
1148+
return %retval : $()
1149+
}
1150+
11331151
// CHECK-LABEL: sil [ossa] @f230_testTryApply : $@convention(thin) <T> (@in T) -> (@out T, @error any Error) {
11341152
// CHECK: bb0(%0 : $*T, %1 : $*T):
11351153
// CHECK: [[F:%.*]] = function_ref @throwsError : $@convention(thin) <τ_0_0> (@in τ_0_0) -> (@out τ_0_0, @error any Error)

0 commit comments

Comments
 (0)