@@ -29,6 +29,14 @@ struct AddressWalkerState {
29
29
static SILValue
30
30
findRootValueForNonTupleTempAllocation (AllocationInst *allocInst,
31
31
AddressWalkerState &state) {
32
+ // These are instructions which we are ok with looking through when
33
+ // identifying our allocation. It must always refer to the entire allocation.
34
+ auto isAlloc = [&](SILValue value) -> bool {
35
+ if (auto *ieai = dyn_cast<InitExistentialAddrInst>(value))
36
+ value = ieai->getOperand ();
37
+ return value == SILValue (allocInst);
38
+ };
39
+
32
40
// Walk from our allocation to one of our writes. Then make sure that the
33
41
// write writes to our entire value.
34
42
for (auto &inst : allocInst->getParent ()->getRangeStartingAtInst (allocInst)) {
@@ -38,21 +46,21 @@ findRootValueForNonTupleTempAllocation(AllocationInst *allocInst,
38
46
continue ;
39
47
40
48
if (auto *copyAddr = dyn_cast<CopyAddrInst>(&inst)) {
41
- if (copyAddr->getDest () == allocInst &&
49
+ if (isAlloc ( copyAddr->getDest ()) &&
42
50
copyAddr->isInitializationOfDest ()) {
43
51
return copyAddr->getSrc ();
44
52
}
45
53
}
46
54
47
55
if (auto *si = dyn_cast<StoreInst>(&inst)) {
48
- if (si->getDest () == allocInst &&
56
+ if (isAlloc ( si->getDest ()) &&
49
57
si->getOwnershipQualifier () != StoreOwnershipQualifier::Assign) {
50
58
return si->getSrc ();
51
59
}
52
60
}
53
61
54
62
if (auto *sbi = dyn_cast<StoreBorrowInst>(&inst)) {
55
- if (sbi->getDest () == allocInst )
63
+ if (isAlloc ( sbi->getDest ()) )
56
64
return sbi->getSrc ();
57
65
}
58
66
0 commit comments