Skip to content

Commit 090a7a3

Browse files
committed
SILCombine: fix a problem with thin_to_thick_function elimination.
The optimizer can generate a thin_to_thick_function conversion from a throwing thin to a non-throwing thick function (in case it can prove that the function is actually not throwing). Therefore, when removing such a conversion from the callee-argument of an apply, we have to check if the new callee (= the argument of the thin_to_thick_function) is a throwing function and set the not-throwing flag in this case. This fixes a SILVerifier crash. rdar://problem/56358645
1 parent 0086eb0 commit 090a7a3

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1586,9 +1586,17 @@ FullApplySite SILCombiner::rewriteApplyCallee(FullApplySite apply,
15861586
TAI->getSubstitutionMap(), arguments,
15871587
TAI->getNormalBB(), TAI->getErrorBB());
15881588
} else {
1589+
auto *AI = cast<ApplyInst>(apply);
1590+
auto fTy = callee->getType().getAs<SILFunctionType>();
1591+
// The optimizer can generate a thin_to_thick_function from a throwing thin
1592+
// to a non-throwing thick function (in case it can prove that the function
1593+
// is not throwing).
1594+
// Therefore we have to check if the new callee (= the argument of the
1595+
// thin_to_thick_function) is a throwing function and set the not-throwing
1596+
// flag in this case.
15891597
return Builder.createApply(apply.getLoc(), callee,
15901598
apply.getSubstitutionMap(), arguments,
1591-
cast<ApplyInst>(apply)->isNonThrowing());
1599+
AI->isNonThrowing() || fTy->hasErrorResult());
15921600
}
15931601
}
15941602

test/SILOptimizer/sil_combine_apply.sil

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,20 @@ bb0(%0 : $*Builtin.Int32, %1 : $*Builtin.Int8):
388388
return %29 : $()
389389
}
390390

391+
sil @actually_not_throwing: $@convention(thin) (Builtin.Int32) -> (@owned Builtin.Int32, @error Error)
392+
393+
// CHECK-LABEL: sil @remove_throwing_thin_to_not_throwing_thick_conversion
394+
// CHECK: [[FN:%[0-9]+]] = function_ref
395+
// CHECK: apply [nothrow] [[FN]](%0)
396+
// CHECK: } // end sil function 'remove_throwing_thin_to_not_throwing_thick_conversion'
397+
sil @remove_throwing_thin_to_not_throwing_thick_conversion : $@convention(thin) (Builtin.Int32) -> @owned Builtin.Int32 {
398+
bb0(%0 : $Builtin.Int32):
399+
%2 = function_ref @actually_not_throwing : $@convention(thin) (Builtin.Int32) -> (@owned Builtin.Int32, @error Error)
400+
%3 = thin_to_thick_function %2 : $@convention(thin) (Builtin.Int32) -> (@owned Builtin.Int32, @error Error) to $@callee_guaranteed (Builtin.Int32) -> @owned Builtin.Int32
401+
%5 = apply %3(%0) : $@callee_guaranteed (Builtin.Int32) -> @owned Builtin.Int32
402+
return %5 : $Builtin.Int32
403+
}
404+
391405
sil @testCombineClosureHelper : $(Builtin.Int32) -> ()
392406

393407
// Test function_ref -> partial_apply -> convert_function -> apply.

0 commit comments

Comments
 (0)