@@ -285,11 +285,20 @@ ABSTRACT_VALUE(SILInstruction, ValueBase)
285
285
INST(ObjCMetatypeToObjectInst, ConversionInst, objc_metatype_to_object, None, DoesNotRelease)
286
286
INST(ObjCExistentialMetatypeToObjectInst, ConversionInst, objc_existential_metatype_to_object, None,
287
287
DoesNotRelease)
288
- // We have to use a MayRead here to block moving the ultimate release
289
- // accross the cast (which reads the type metadata). With Semantic SIL we
290
- // should be able to move this back to None - it should model the scoping
291
- // and forbid the compiler from moving the ultimate retain.
288
+ // unconditional_checked_cast_value reads the source value and produces
289
+ // a new value with a potentially different representation.
292
290
INST(UnconditionalCheckedCastValueInst, ConversionInst, unconditional_checked_cast_value, MayRead, MayRelease)
291
+ // unconditional_checked_cast_inst is only MayRead to prevent a subsequent
292
+ // release of the cast's source from being hoisted above the cast:
293
+ // retain X
294
+ // Y = unconditional_checked_cast_inst X
295
+ // _ = Y
296
+ // release X // This release cannot be reordered with the cast.
297
+ //
298
+ // With Semantic SIL, this pattern of unbalanced retain/release
299
+ // should never happen. Since unconditional_checked_cast is a
300
+ // scalar cast that doesn't affect the value's representation, its
301
+ // side effect can then be modeled as None.
293
302
INST(UnconditionalCheckedCastInst, ConversionInst, unconditional_checked_cast, MayRead, DoesNotRelease)
294
303
VALUE_RANGE(ConversionInst, UpcastInst, UnconditionalCheckedCastInst)
295
304
INST(IsNonnullInst, SILInstruction, is_nonnull, None, DoesNotRelease)
0 commit comments