@@ -801,6 +801,10 @@ SILCombiner::buildConcreteOpenedExistentialInfoFromSoleConformingType(
801801 SILBuilderWithScope b (std::next (OER->getIterator ()), Builder);
802802 auto loc = RegularLocation::getAutoGeneratedLocation ();
803803 SoleCEI.ConcreteValue = b.createUncheckedRefCast (loc, OER, concreteSILType);
804+ if (F->hasOwnership () &&
805+ SoleCEI.ConcreteValue ->getOwnershipKind () == OwnershipKind::Owned) {
806+ SoleCEI.ConcreteValueNeedsFixup = true ;
807+ }
804808 return COAI;
805809 }
806810
@@ -831,8 +835,19 @@ SILCombiner::buildConcreteOpenedExistentialInfo(Operand &ArgOperand) {
831835 // Build a ConcreteOpenedExistentialInfo following the data flow chain of the
832836 // ArgOperand through the open_existential backward to an init_existential.
833837 ConcreteOpenedExistentialInfo COEI (ArgOperand);
834- if (COEI.CEI )
838+ if (COEI.CEI ) {
839+ auto ConcreteValue = COEI.CEI ->ConcreteValue ;
840+ if (ConcreteValue->getFunction ()->hasOwnership () &&
841+ ConcreteValue->getOwnershipKind () == OwnershipKind::Owned) {
842+ SILBuilderWithScope b (COEI.OAI .OpenedArchetypeValue ->getNextInstruction (),
843+ Builder);
844+ auto loc = RegularLocation::getAutoGeneratedLocation ();
845+ COEI.CEI ->ConcreteValue = b.createUncheckedRefCast (
846+ loc, COEI.OAI .OpenedArchetypeValue , ConcreteValue->getType ());
847+ COEI.CEI ->ConcreteValueNeedsFixup = true ;
848+ }
835849 return COEI;
850+ }
836851
837852 // Use SoleConformingType information.
838853 return buildConcreteOpenedExistentialInfoFromSoleConformingType (ArgOperand);
@@ -1126,6 +1141,7 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
11261141
11271142 // Transform the parameter arguments.
11281143 SmallVector<ConcreteArgumentCopy, 4 > concreteArgCopies;
1144+ llvm::SmallMapVector<SILValue, SILValue, 4 > valuesToReplace;
11291145 for (unsigned EndIdx = Apply.getNumArguments (); ArgIdx < EndIdx; ++ArgIdx) {
11301146 auto ArgIt = COAIs.find (ArgIdx);
11311147 if (ArgIt == COAIs.end ()) {
@@ -1178,6 +1194,9 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
11781194 concreteArgCopies.push_back (*argSub);
11791195 NewArgs.push_back (argSub->tempArg );
11801196 } else {
1197+ if (CEI.ConcreteValueNeedsFixup ) {
1198+ valuesToReplace[OAI.OpenedArchetypeValue ] = CEI.ConcreteValue ;
1199+ }
11811200 NewArgs.push_back (CEI.ConcreteValue );
11821201 }
11831202
@@ -1239,9 +1258,8 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
12391258 // SILCombine Worklist.
12401259 InstructionDeleter deleter;
12411260 for (SILInstruction *inst : *Builder.getTrackingList ()) {
1242- deleter.trackIfDead (inst);
1261+ deleter.deleteIfDead (inst, false );
12431262 }
1244- deleter.cleanupDeadInstructions ();
12451263 Builder.getTrackingList ()->clear ();
12461264 return nullptr ;
12471265 }
@@ -1283,6 +1301,20 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
12831301 cleanupBuilder.createDeallocStack (cleanupLoc, argCopy.tempArg );
12841302 }
12851303 }
1304+ // Replace all uses of the opened existential with the unconditional cast to
1305+ // concrete type.
1306+ for (auto &valuePair : valuesToReplace) {
1307+ auto openedExistential = valuePair.first ;
1308+ auto uncheckedCast = valuePair.second ;
1309+ SmallVector<Operand *> uses (openedExistential->getNonTypeDependentUses ());
1310+ for (auto use : uses) {
1311+ auto *user = use->getUser ();
1312+ if (user == cast<SingleValueInstruction>(uncheckedCast)) {
1313+ continue ;
1314+ }
1315+ use->set (uncheckedCast);
1316+ }
1317+ }
12861318 return NewApply.getInstruction ();
12871319}
12881320
0 commit comments