The LICM pass's hoistAndSinkLoadAndStore incorrectly determined load/store
ownership based on firstStore.storeOwnership rather than the address type.
This PR fixes it by determining ownership based on the address type's triviality:
If `load [trivial]` only loads a "part" of a stored value, which itself is non-trivial, the pass crashes with an ownership error.
The fix is to wrap the projection instructions (e.g. `struct_extract`) inside a borrow scope. This is correctly done in `createProjectionAndCopy`.
https://github.com/swiftlang/swift/issues/89255
rdar://177430359
So far we supported hoisting a `load [take]` which "takes" just a part of a stored value (i.e. a projected value).
This works as long as no other struct/tuple field is also loaded in the loop.
If this is the case it causes an ownership error.
The fix is to disallow hoisting projected `load [take]` instructions.
This new OSSA invariant simplifies many optimizations because they don't have to take care of the corner case of incomplete lifetimes in dead-end blocks.
The implementation basically consists of these changes:
* add the lifetime completion utility
* add a flag in SILFunction which tells optimization that they need to run the lifetime completion utility
* let all optimizations complete lifetimes if necessary
* enable the ownership verifier to check complete lifetimes
Usually `load [take]` is not hoisted anyway, because there must be another instruction in the loop which re-initializes the loaded memory location.
However, this is not necessarily true for alloc_stack locations with dynamic lifetime, e.g. a pack-loop which is specialized for a single pack element (at runtime the loop is only executed once).
Fixes a SIL ownership verifier crash
rdar://167504916
This is wrong for hoisted load instructions because we don't check for aliasing in the pre-header.
And for side-effect-free instructions it's not really necessary, because that can cleanup CSE afterwards.
Fixes a miscompile
rdar://164034503