[DestroyAddrHoisting] Skip init_enum_data_addrs.

A destroy of an `init_enum_data_addr` is not equivalent to a destroy of
the whole enum's address.  Treat such destroys just like destroys of
`struct_element_addr`s are treated: by bailing out.

rdar://152431332
This commit is contained in:
Nate Chandler
2025-06-03 12:49:56 -07:00
parent 5af84375f2
commit 625e6d77a3
2 changed files with 50 additions and 0 deletions

View File

@@ -164,6 +164,20 @@ protected:
bool visitStore(Operand *use) override { return recordUser(use->getUser()); }
bool visitDestroy(Operand *use) override {
// An init_enum_data_addr is viewed as an "identity projection", rather than
// a proper projection like a struct_element_addr. As a result, its
// destroys are passed directly to visitors. But such addresses aren't
// quite equivalent to the original address. Specifically, a destroy of an
// init_enum_data_addr cannot in general be replaced with a destroy of the
// whole enum. The latter destroy is only equivalent to the former if there
// has been an `inject_enum_addr`.
//
// Handle a destroy of such a projection just like we handle the destroy of
// a struct_element_addr: by bailing out.
if (isa<InitEnumDataAddrInst>(
stripAccessAndAccessStorageCasts(use->get()))) {
return false;
}
originalDestroys.insert(use->getUser());
return true;
}