Skip to content

Commit c322166

Browse files
authored
Merge pull request swiftlang#35941 from eeckstein/fix-simplify-ref-cast-5.4
[5.4] SILCombine: don't create a strong_retain/strong_release with an Optional<reference> as an operand
2 parents 53cfe01 + dbf1aa4 commit c322166

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

lib/SILOptimizer/Analysis/SimplifyInstruction.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,13 @@ static SILValue simplifyDeadCast(SingleValueInstruction *Cast) {
348348
for (Operand *op : Cast->getUses()) {
349349
switch (op->getUser()->getKind()) {
350350
case SILInstructionKind::DestroyValueInst:
351+
break;
351352
case SILInstructionKind::StrongReleaseInst:
352353
case SILInstructionKind::StrongRetainInst:
354+
// ref-casts can cast from an Optional<Classtype>. But strong_retain/
355+
// strong_release don't accept an optional.
356+
if (!Cast->getOperand(0)->getType().isReferenceCounted(Cast->getModule()))
357+
return SILValue();
353358
break;
354359
default:
355360
return SILValue();

test/SILOptimizer/sil_combine.sil

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,20 @@ bb0(%0 : $C1):
836836
return %0 : $C1
837837
}
838838

839+
// strong_retain/strong_release don't accept an Optional<reference>.
840+
//
841+
// CHECK-LABEL: sil @dontOptimizeRefCastOfOptional
842+
// CHECK: %1 = unchecked_ref_cast %0
843+
// CHECK: strong_retain %1
844+
// CHECK: } // end sil function 'dontOptimizeRefCastOfOptional'
845+
sil @dontOptimizeRefCastOfOptional : $@convention(thin) (@guaranteed Optional<C1>) -> () {
846+
bb0(%0 : $Optional<C1>):
847+
%1 = unchecked_ref_cast %0 : $Optional<C1> to $C1
848+
strong_retain %1 : $C1
849+
%3 = tuple ()
850+
return %3 : $()
851+
}
852+
839853
// CHECK-LABEL: sil @dead_end_cow_mutation
840854
// CHECK: bb0
841855
// CHECK-NEXT: strong_retain %0

0 commit comments

Comments
 (0)