@@ -765,6 +765,14 @@ void SILCombiner::replaceWitnessMethodInst(
765765 eraseInstFromFunction (*WMI);
766766}
767767
768+ static bool hasUse (SILValue v, Operand *op) {
769+ for (Operand *use : v->getUses ()) {
770+ if (use == op)
771+ return true ;
772+ }
773+ return false ;
774+ }
775+
768776// This function determines concrete type of an opened existential argument
769777// using ProtocolConformanceAnalysis. The concrete type of the argument can be a
770778// class, struct, or an enum.
@@ -839,6 +847,13 @@ SILCombiner::buildConcreteOpenedExistentialInfoFromSoleConformingType(
839847 // Prepare the code by adding UncheckedCast instructions that cast opened
840848 // existentials to concrete types. Set the ConcreteValue of CEI.
841849 if (auto *OER = dyn_cast<OpenExistentialRefInst>(OAI.OpenedArchetypeValue )) {
850+ // Make sure that the existential value outlives the apply. This is the case
851+ // if the apply uses it as argument operand.
852+ if (OER->getOwnershipKind () == OwnershipKind::Owned &&
853+ !hasUse (OER, &ArgOperand)) {
854+ return std::nullopt ;
855+ }
856+
842857 SILBuilderWithScope b (std::next (OER->getIterator ()), Builder);
843858 auto loc = RegularLocation::getAutoGeneratedLocation ();
844859 SoleCEI.ConcreteValue = b.createUncheckedRefCast (loc, OER, concreteSILType);
@@ -880,6 +895,11 @@ SILCombiner::buildConcreteOpenedExistentialInfo(Operand &ArgOperand) {
880895 auto ConcreteValue = COEI.CEI ->ConcreteValue ;
881896 if (ConcreteValue->getFunction ()->hasOwnership () &&
882897 ConcreteValue->getOwnershipKind () == OwnershipKind::Owned) {
898+ // Make sure that the existential value outlives the apply. This is the case
899+ // if the apply uses it as argument operand.
900+ if (!hasUse (COEI.OAI .OpenedArchetypeValue , &ArgOperand))
901+ return std::nullopt ;
902+
883903 SILBuilderWithScope b (COEI.OAI .OpenedArchetypeValue ->getNextInstruction (),
884904 Builder);
885905 auto loc = RegularLocation::getAutoGeneratedLocation ();
0 commit comments