Commit Graph

26 Commits

Author SHA1 Message Date
Meghana Gupta adf9b5c94b Fix LICM producing illegal load [trivial] on non-trivial address types
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:
2026-05-22 16:55:46 -07:00
Erik Eckstein 096ede496f LoopInvariantCodeMotion: fix an ownership error caused by hoisting trivial sub-projection loads
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
2026-05-21 08:18:02 +02:00
Erik Eckstein 83739a0462 LoopInvariantCodeMotion: fix a crash when trying to hoist load [take]
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.
2026-05-21 07:54:09 +02:00
Aidan Hall 070f7923d9 Bridging: Rename FunctionConvention.results to resultsWithError
This matches the name of the C++ method it bridges, and avoids the ambiguity of
the previous name.
2026-05-18 14:47:05 +01:00
Erik Eckstein 18063707b5 Optimizer: enable complete OSSA lifetimes throughout the pass pipeline
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
2026-01-22 17:41:48 +01:00
Erik Eckstein b2791f1b60 LoopInvariantCodeMotion: don't hoist load [take]
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
2026-01-05 10:41:44 +01:00
Erik Eckstein 50c299e0bf LoopInvariantCodeMotion: don't reuse existing instructions in the loop pre-header
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
2025-11-18 21:23:13 +01:00
Erik Eckstein 5b8a1a7b68 LoopInvariantCodeMotion: don't extend "read" access scopes over memory writes to the same address.
We must not do this even if the write is _not_ in an access scope, because this would confuse alias analysis.

Fixes a mis-compile.
2025-10-22 20:55:22 +02:00
Erik Eckstein dafb43b124 LoopInvariantCodeMotion: a small code cleanup
NFC
2025-10-22 20:55:22 +02:00
Erik Eckstein 55cdc31936 LoopInvariantCodeMotion: a small refactoring
which is now possible as we removed the "fallthrough" from the previous case
2025-10-06 17:57:12 +02:00
Erik Eckstein e88096e971 LoopInvariantCodeMotion: fix check for hoisting load_borrow instructions
We need to check aliasing for all kind of side-effect instructions, not just stores and destroys
2025-10-06 17:57:12 +02:00
Erik Eckstein b527020364 LoopInvariantCodeMotion: bail on split load [take]
We currently don't support split `load [take]`, i.e. `load [take]` which does _not_ load all non-trivial fields of the initial value.
2025-09-30 10:39:51 +02:00
Erik Eckstein fc6302e3e9 LoopInvariantCodeMotion: correctly handle load [copy]
When moving loads and stores out of a loop, a `load [copy]` must be replaced by a `copy_value`.
2025-09-30 10:39:51 +02:00
Erik Eckstein 7bbe5c6fe2 LoopInvariantCodeMotion: don't hoist loads and stores if the memory location is not initialized at loop exits.
If the memory is not initialized at all exits, it would be wrong to insert stores at exit blocks.
2025-09-30 10:39:51 +02:00
Jakub Florek aebebd9ee2 Merge pull request #84463 from MAJKFL/fix-licm-missing-earlier-materializable-projection-check
LICM fix missing materializable projection check
2025-09-24 17:19:39 +01:00
Jakub Florek 6788017cfb Add earlier check before load projection that bails when it's not materializable. 2025-09-24 11:49:59 +01:00
Jakub Florek b12e0ef554 Don't hoist scoped instructions in dead end loops. 2025-09-22 12:12:19 +01:00
Jakub Florek 38f28c1049 Reapply "Merge pull request #84045 from MAJKFL/new-sil-licm-pass-copy-ownership"
This reverts commit d2cd281d4c.
2025-09-19 16:06:35 +01:00
Jakub Florek d2cd281d4c Revert "Merge pull request #84045 from MAJKFL/new-sil-licm-pass-copy-ownership"
This reverts commit a5c6156525, reversing
changes made to 2b6ea81b9e.
2025-09-17 15:52:48 +01:00
Jakub Florek e84bc084f4 Check for aliasing destroy_addr before hoisting load_borrow - end_borrow pair. 2025-09-15 12:42:30 +01:00
Jakub Florek 0b75a81b65 Add licm Ownership support. 2025-09-10 16:18:51 +01:00
Jakub Florek 6955bdf564 Merge pull request #84173 from MAJKFL/fix-licm-not-projecting-load-path
Fix licm not projecting load path before load splitting.
2025-09-09 22:43:53 +01:00
Jakub Florek be72ad726a Fix licm not projecting load path before load splitting. 2025-09-09 17:02:29 +01:00
Jakub Florek e905df42f2 Fix read apply hoisted with conflicting write apply. 2025-09-02 15:53:53 +01:00
Jakub Florek bab00113b2 Fix licm handling of unreferenceable storage. 2025-08-29 12:46:27 +01:00
Jakub Florek 07ac8b3478 Add new loop invariant code motion. 2025-08-28 21:00:33 +01:00