Skip to content

Commit b2e34b2

Browse files
Merge pull request #61963 from nate-chandler/opaque-values/1/20221107
[AddressLowering] Handle try_apply with enum'd return.
2 parents 0592979 + 93e5701 commit b2e34b2

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,6 +3172,12 @@ class DefRewriter : SILInstructionVisitor<DefRewriter> {
31723172
protected:
31733173
// Set the storage address for an opaque block arg and mark it rewritten.
31743174
void rewriteArg(SILPhiArgument *arg) {
3175+
if (auto *tai =
3176+
dyn_cast_or_null<TryApplyInst>(arg->getTerminatorForResult())) {
3177+
CallArgRewriter(tai, pass).rewriteArguments();
3178+
ApplyRewriter(tai, pass).convertApplyWithIndirectResults();
3179+
return;
3180+
}
31753181
LLVM_DEBUG(llvm::dbgs() << "REWRITE ARG "; arg->dump());
31763182
if (storage.storageAddress)
31773183
LLVM_DEBUG(llvm::dbgs() << " STORAGE "; storage.storageAddress->dump());
@@ -3371,6 +3377,9 @@ static void rewriteFunction(AddressLoweringState &pass) {
33713377
DefRewriter::rewriteValue(valueDef, pass);
33723378
valueAndStorage.storage.markRewritten();
33733379
}
3380+
// The def of interest may have been changed by rewriteValue. Get that
3381+
// redefinition back out of the ValueStoragePair.
3382+
valueDef = valueAndStorage.value;
33743383
// Rewrite a use of any non-address value mapped to storage (does not
33753384
// include the already rewritten uses of indirect arguments).
33763385
if (valueDef->getType().isAddress())

test/SILOptimizer/address_lowering.sil

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,47 @@ bb2(%9 : $Error):
12471247
throw %9 : $Error
12481248
}
12491249

1250+
// CHECK-LABEL: sil [ossa] @f261_testTryApplyIntoEnum : $@convention(thin) <T> () -> (@out Optional<T>, @error any Error) {
1251+
// CHECK: {{bb[0-9]+}}([[OUT_ADDR:%[^,]+]] : $*Optional<T>):
1252+
// CHECK: [[SOME_ADDR:%[^,]+]] = init_enum_data_addr %0 : $*Optional<T>, #Optional.some!enumelt
1253+
// CHECK: try_apply undef<T>([[SOME_ADDR]]) {{.*}}, normal [[NORMAL:bb[0-9]+]], error {{bb[0-9]+}}
1254+
// CHECK: [[NORMAL]]
1255+
// CHECK: inject_enum_addr [[OUT_ADDR]] : $*Optional<T>, #Optional.some!enumelt
1256+
// CHECK-LABEL: } // end sil function 'f261_testTryApplyIntoEnum'
1257+
sil [ossa] @f261_testTryApplyIntoEnum : $@convention(thin) <T> () -> (@out Optional<T>, @error any Error) {
1258+
entry:
1259+
try_apply undef<T>() : $@convention(thin) <T> () -> (@out T, @error any Error), normal okay, error nopers
1260+
1261+
okay(%instance : @owned $T):
1262+
%some = enum $Optional<T>, #Optional.some!enumelt, %instance : $T
1263+
return %some : $Optional<T>
1264+
1265+
nopers(%error : @owned $any Error):
1266+
throw %error : $any Error
1267+
}
1268+
1269+
// CHECK-LABEL: sil [ossa] @f262_testTryApplyIntoPhi : {{.*}} {
1270+
// CHECK: {{bb[0-9]+}}([[ADDR:%[^,]+]] :
1271+
// CHECK: try_apply undef<R>([[ADDR]]) {{.*}}, normal [[NORMAL:bb[0-9]+]]
1272+
// CHECK: [[NORMAL]](%2 : $()):
1273+
// CHECK: br [[EXIT:bb[0-9]+]]
1274+
// CHECK: [[EXIT]]:
1275+
// CHECK: return {{%[^,]+}} : $()
1276+
// CHECK-LABEL: } // end sil function 'f262_testTryApplyIntoPhi'
1277+
sil [ossa] @f262_testTryApplyIntoPhi : $@convention(thin) <R> () -> (@out R, @error any Error) {
1278+
entry:
1279+
try_apply undef<R>() : $@convention(thin) <U> () -> (@out U, @error any Error), normal good, error bad
1280+
1281+
good(%instance : @owned $R):
1282+
br exit(%instance : $R)
1283+
1284+
exit(%instance_2 : @owned $R):
1285+
return %instance_2 : $R
1286+
1287+
bad(%41 : @owned $any Error):
1288+
throw %41 : $any Error
1289+
}
1290+
12501291
// CHECK-LABEL: sil [ossa] @fixeeLifetime : {{.*}} {
12511292
// CHECK: {{bb[0-9]+}}([[ADDR:%[^,]+]] : $*T):
12521293
// CHECK: fix_lifetime [[ADDR]]

0 commit comments

Comments
 (0)