Skip to content

Commit 3ba9356

Browse files
committed
SimplifyCFG: fix try_apply -> apply transformation for indirect error results
Indirect error results must not be included in the final apply arguments which they are not present in the callee.
1 parent 699b165 commit 3ba9356

File tree

3 files changed

+68
-4
lines changed

3 files changed

+68
-4
lines changed

include/swift/SIL/SILFunctionConventions.h

+6
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,12 @@ class SILFunctionConventions {
242242
return 0;
243243
}
244244

245+
bool isArgumentIndexOfIndirectErrorResult(unsigned idx) {
246+
unsigned indirectResults = getNumIndirectSILResults();
247+
return idx >= indirectResults &&
248+
idx < indirectResults + getNumIndirectSILErrorResults();
249+
}
250+
245251
/// Are any SIL results passed as address-typed arguments?
246252
bool hasIndirectSILResults() const { return getNumIndirectSILResults() != 0; }
247253
bool hasIndirectSILErrorResults() const { return getNumIndirectSILErrorResults() != 0; }

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -2550,18 +2550,21 @@ bool SimplifyCFG::simplifyTryApplyBlock(TryApplyInst *TAI) {
25502550
auto context = TAI->getFunction()->getTypeExpansionContext();
25512551
SmallVector<SILValue, 8> Args;
25522552
unsigned numArgs = TAI->getNumArguments();
2553+
unsigned calleeArgIdx = 0;
25532554
for (unsigned i = 0; i < numArgs; ++i) {
25542555
auto Arg = TAI->getArgument(i);
2556+
if (origConv.isArgumentIndexOfIndirectErrorResult(i) &&
2557+
!targetConv.isArgumentIndexOfIndirectErrorResult(i)) {
2558+
continue;
2559+
}
25552560
// Cast argument if required.
25562561
std::tie(Arg, std::ignore) = castValueToABICompatibleType(
25572562
&Builder, TAI->getLoc(), Arg, origConv.getSILArgumentType(i, context),
2558-
targetConv.getSILArgumentType(i, context), {TAI});
2563+
targetConv.getSILArgumentType(calleeArgIdx, context), {TAI});
25592564
Args.push_back(Arg);
2565+
calleeArgIdx += 1;
25602566
}
25612567

2562-
assert(calleeConv.getNumSILArguments() == Args.size()
2563-
&& "The number of arguments should match");
2564-
25652568
LLVM_DEBUG(llvm::dbgs() << "replace with apply: " << *TAI);
25662569

25672570
// If the new callee is owned, copy it to extend the lifetime

test/SILOptimizer/simplify_cfg_ossa.sil

+55
Original file line numberDiff line numberDiff line change
@@ -1788,3 +1788,58 @@ bb6(%14 : $FakeBool):
17881788
return %14 : $FakeBool
17891789
}
17901790

1791+
struct Err: Error {
1792+
var i: Int
1793+
}
1794+
1795+
sil @callee1 : $@convention(thin) (Int) -> @out Int
1796+
sil @callee2 : $@convention(thin) (Int) -> (@out Int, @error_indirect Err)
1797+
1798+
// CHECK-LABEL: sil [ossa] @try_apply_to_apply_with_indirect_error1 :
1799+
// CHECK: [[OUT:%.*]] = alloc_stack $Int
1800+
// CHECK: apply {{%[0-9]+}}([[OUT]], %0)
1801+
// CHECK: } // end sil function 'try_apply_to_apply_with_indirect_error1'
1802+
sil [ossa] @try_apply_to_apply_with_indirect_error1 : $@convention(method) (Int) -> () {
1803+
bb0(%0 : $Int):
1804+
%1 = function_ref @callee1 : $@convention(thin) (Int) -> @out Int
1805+
%2 = thin_to_thick_function %1 : $@convention(thin) (Int) -> @out Int to $@noescape @callee_guaranteed (Int) -> @out Int
1806+
%3 = convert_function %2 : $@noescape @callee_guaranteed (Int) -> @out Int to $@noescape @callee_guaranteed (Int) -> (@out Int, @error_indirect Err), forwarding: @owned
1807+
%4 = alloc_stack $Int
1808+
%5 = alloc_stack $Err
1809+
try_apply %3(%4, %5, %0) : $@noescape @callee_guaranteed (Int) -> (@out Int, @error_indirect Err), normal bb10, error bb11
1810+
1811+
bb10(%7 : $()):
1812+
dealloc_stack %5 : $*Err
1813+
dealloc_stack %4 : $*Int
1814+
destroy_value %3 : $@noescape @callee_guaranteed (Int) -> (@out Int, @error_indirect Err)
1815+
%r = tuple ()
1816+
return %r : $()
1817+
1818+
bb11:
1819+
dealloc_stack %5 : $*Err
1820+
dealloc_stack %4 : $*Int
1821+
destroy_value %3 : $@noescape @callee_guaranteed (Int) -> (@out Int, @error_indirect Err)
1822+
unreachable
1823+
}
1824+
1825+
// CHECK-LABEL: sil [ossa] @try_apply_to_apply_with_indirect_error2 :
1826+
// CHECK: [[OUT:%.*]] = alloc_stack $Int
1827+
// CHECK: [[ERR:%.*]] = alloc_stack $Err
1828+
// CHECK: apply [nothrow] {{%[0-9]+}}([[OUT]], [[ERR]], %0)
1829+
// CHECK: } // end sil function 'try_apply_to_apply_with_indirect_error2'
1830+
sil [ossa] @try_apply_to_apply_with_indirect_error2 : $@convention(method) (Int) -> () {
1831+
bb0(%0 : $Int):
1832+
%1 = function_ref @callee2 : $@convention(thin) (Int) -> (@out Int, @error_indirect Err)
1833+
%4 = alloc_stack $Int
1834+
%5 = alloc_stack $Err
1835+
try_apply %1(%4, %5, %0) : $@convention(thin) (Int) -> (@out Int, @error_indirect Err), normal bb10, error bb11
1836+
1837+
bb10(%7 : $()):
1838+
dealloc_stack %5 : $*Err
1839+
dealloc_stack %4 : $*Int
1840+
%r = tuple ()
1841+
return %r : $()
1842+
1843+
bb11:
1844+
unreachable
1845+
}

0 commit comments

Comments
 (0)