@@ -264,8 +264,16 @@ static bool fixupReferenceCounts(
264264 return invalidatedStackNesting;
265265}
266266
267- static SILValue cleanupLoadedCalleeValue (SILValue calleeValue, LoadInst *li) {
268- auto *pbi = dyn_cast<ProjectBoxInst>(li->getOperand ());
267+ // Handle the case where the callee of the apply is either a load or a
268+ // project_box that was used by a deleted load. If we fail to optimize,
269+ // return an invalid SILValue.
270+ static SILValue cleanupLoadedCalleeValue (SILValue calleeValue) {
271+ auto calleeSource = calleeValue;
272+ auto *li = dyn_cast<LoadInst>(calleeValue);
273+ if (li) {
274+ calleeSource = li->getOperand ();
275+ }
276+ auto *pbi = dyn_cast<ProjectBoxInst>(calleeSource);
269277 if (!pbi)
270278 return SILValue ();
271279 auto *abi = dyn_cast<AllocBoxInst>(pbi->getOperand ());
@@ -274,17 +282,18 @@ static SILValue cleanupLoadedCalleeValue(SILValue calleeValue, LoadInst *li) {
274282
275283 // The load instruction must have no more uses or a single destroy left to
276284 // erase it.
277- if (li->getFunction ()->hasOwnership ()) {
278- // TODO: What if we have multiple destroy_value? That should be ok as well.
279- auto *dvi = li->getSingleUserOfType <DestroyValueInst>();
280- if (!dvi)
285+ if (li) {
286+ if (li->getFunction ()->hasOwnership ()) {
287+ // TODO: What if we have multiple destroy_value? That should be ok.
288+ auto *dvi = li->getSingleUserOfType <DestroyValueInst>();
289+ if (!dvi)
290+ return SILValue ();
291+ dvi->eraseFromParent ();
292+ } else if (!li->use_empty ()) {
281293 return SILValue ();
282- dvi->eraseFromParent ();
283- } else if (!li->use_empty ()) {
284- return SILValue ();
294+ }
295+ li->eraseFromParent ();
285296 }
286- li->eraseFromParent ();
287-
288297 // Look through uses of the alloc box the load is loading from to find up to
289298 // one store and up to one strong release.
290299 PointerUnion<StrongReleaseInst *, DestroyValueInst *> destroy;
@@ -356,15 +365,8 @@ static SILValue cleanupLoadedCalleeValue(SILValue calleeValue, LoadInst *li) {
356365// / longer necessary after inlining.
357366static void cleanupCalleeValue (SILValue calleeValue,
358367 bool &invalidatedStackNesting) {
359- // Handle the case where the callee of the apply is a load instruction. If we
360- // fail to optimize, return. Otherwise, see if we can look through other
361- // abstractions on our callee.
362- if (auto *li = dyn_cast<LoadInst>(calleeValue)) {
363- calleeValue = cleanupLoadedCalleeValue (calleeValue, li);
364- if (!calleeValue) {
365- return ;
366- }
367- }
368+ if (auto loadedValue = cleanupLoadedCalleeValue (calleeValue))
369+ calleeValue = loadedValue;
368370
369371 calleeValue = stripCopiesAndBorrows (calleeValue);
370372
0 commit comments