Commit Graph

313 Commits

Author SHA1 Message Date
Erik Eckstein
972fde7e70 LetPropertyLowering: remove redundant phis after ssa-update
This is needed after running the SSAUpdater, because the updater can insert unnecessary phis in the middle of the original liverange of a value.

Fixes an ownership error.
rdar://153229472
2025-07-04 20:37:45 +02:00
Andrew Trick
43193b6a4d Fix LocalVariableUtils switch_enum_addr.
switch_enum_addr was being treated like a store instruction, which killed
the local enum's liveness. This could result local variable analysis reporting a
shorter lifetime for the local.

This showed up as a missing exclusivity diagnostic because an access scope was
not fully extended across a dependent local variable of Optional type.

This prevents the following pattern from miscompiling. It should report an exclusivity violation:

  var mutableView = getOpaqueOptionalView(holder: &holder)!
  mutate(&holder)
  mutableView.modify()

Fixes rdar://151231236 ([~Escapable] Missing 'overlapping acceses' error when
called from client code, but exact same code produces error in same module)

(cherry picked from commit fe9c0dd735)
2025-06-28 09:30:55 -07:00
Andrew Trick
2c98863499 Fix MutableSpan exclusive access to unsafe pointers
This fix enables exclusive access to a MutableSpan created from an UnsafeMutablePointer.

The compiler has a special case that allows MutableSpan to depend on a mutable
pointer *without* extending that pointer's access scope. That lets us implement
standard library code like this:

    mutating public func extracting(droppingLast k: Int) -> Self {
      //...
      let newSpan = unsafe Self(_unchecked: _pointer, byteCount: newCount)
      return unsafe _overrideLifetime(newSpan, mutating: &self)

Refine this special case so that is does not apply to inout parameters where the
programmer has an expectation that the unsafe pointer is not copied when being
passed as an argument. Now, we safely get an exclusivity violation when creating
two mutable spans from the same pointer field:

    @lifetime(&self)
    mutating func getSpan() -> MutableSpan<T> {
      let span1 = makeMutableSpan(&self.pointer)
      let span2 = makeMutableSpan(&self.pointer) // ERROR: overlapping access
      return span1
    }

If we don't fix this now, it will likely be source breaking in the future.

Fixes rdar://153745332 (Swift allows constructing two MutableSpans to
the same underlying pointer)

(cherry picked from commit 7c5d4b8b6d)

--- CCC ---

Explanation: Fix MutableSpan exclusive access to unsafe pointers This
fix enables exclusive access to a MutableSpan created from an
UnsafeMutablePointer.

Scope: Affects users of MutableSpan when initializing them from an unsafe pointer.

Radar/SR Issue: rdar://153745332 (Swift allows constructing two
MutableSpans to the same underlying pointer)

main PR: https://github.com/swiftlang/swift/pull/82450

Risk: Low. This only affects users of an API that requires lifetime
dependence. Without using an experimental feature, this only applies
to the initializers of Mutable[Raw]Span.

Testing: Added source-level unit tests

Reviewer: TBD
2025-06-24 00:18:29 -07:00
Andrew Trick
3dd1fb2518 Fix lifetime dependence diagnostics on Void types.
Allow a dependence on Void to be considered immortal. This is the ultimate
override in cases where no other code pattern is supported yet.

(cherry picked from commit 36d2b5bee4)
2025-06-24 00:11:47 -07:00
Andrew Trick
9bcc3f41dc LifetimeDependenceScopeFixup: crash handling dead-end coroutine
When extending a coroutine, handle the end_borrow instruction used to end a
coroutine lifetime at a dead-end block.

Fixes rdar://153479358 (Compiler crash when force-unwrapping optional ~Copyable type)

(cherry picked from commit 5b5f370ce1)
2025-06-17 09:59:14 -07:00
Meghana Gupta
d5b82a3b7c [6.2] Fix an inliner crash when inlining begin_apply with scoped lifetime dependence 2025-06-13 14:18:29 -07:00
Andrew Trick
0116dc0ff9 LifetimeDependenceScopeFixup: handle yielded value copies.
When extending an access scope over a coroutines, instead of simply
considering the lifetime of the coroutine scope, recurse through all
uses of yielded values. They may be copyable, non-Escapable values
that depend on the coroutine operand.

Fixes rdar://152693622 (Extend coroutines over copied yields)

(cherry picked from commit 227f8028e8)
2025-06-05 20:24:18 -07:00
Andrew Trick
3691eedab9 [NFC] LifetimeDependence: fix internal debug output
(cherry picked from commit 95f7a12c98)
2025-06-05 20:24:18 -07:00
Andrew Trick
fb2a6ee9a8 LifetimeDependenceDiagnostics: fix source loc for implicit variables
Diagnostics on an indirect result ($return_value) did not report a source
location.

(cherry picked from commit c030b78c7d)
2025-06-04 12:03:35 -07:00
Andrew Trick
b862300097 LifetimeDependenceDiagnostics: diagnose indirect closure results.
Add support for diagnosing calls to closures that return a generic
non-Escapable result.

Closures do not yet model lifetime dependencies. The diagnostics have
a special case for handling nonescaple result with no lifetime
dependence, but it previously only handled direct results. This fix handles
cases like the following:

    func callIndirectClosure<T>(f: () -> NE<T>) -> NE<T> {
      f()
    }

Fixes rdar://134318846 ([nonescapable] diagnose function types with nonescapable results)

(cherry picked from commit 1d09c06ab1)
2025-06-04 12:03:35 -07:00
Erik Eckstein
f69793cc5f DeadStoreElimination: don't assume that the operand of an dealloc_stack is an alloc_stack.
It can also be a `partial_apply`.
Fixes a compiler crash
https://github.com/swiftlang/swift/issues/81698
rdar://151822502
2025-05-23 06:48:45 +02:00
Meghana Gupta
f9f709b7c3 Fix newly introduced warnings in LifetimeDependenceScopeFixup 2025-05-05 11:26:38 -07:00
Zachary 'Clack' Cole
f3380efa9d Merge pull request #81240 from clackary/cherrypick/ossa-partial-apply-80662
[6.2 🍒] Fix ownership issues with sequences of partial_apply's in AutoDiff closure specialization pass
2025-05-02 13:20:34 -06:00
Andrew Trick
6f05d80161 LifetimeDependenceDefUseAddressWalker: avoid infinite recursion.
This utility is used by DependentAddressUseDefWalker which now conservatively
follows all possible uses. This could result in the same address being reached
multiple times during a def-use walk. Ensure that we don't infinitely recurse.

There is no small test case for this, but the fix is trivial and standard
practice for such walkers, and this is hit quickly in real usage, so there is no
danger of it regressing.

Fixes rdar://150403948 ([nonescapable] Infinite recursion compiler crash in
lifetime dependence checking)

(cherry picked from commit 4512927d2b)
2025-05-01 17:10:59 -07:00
Anton Korobeynikov
35678bffc2 [6.2 🍒]
Fix ownership issues with sequences of partial_apply's in AutoDiff closure specialization pass (#80662)

Each partial_apply consumes its arguments, therefore we should never release intermediate ones in the sequence of closures.

Fixes #78847

(cherry picked from commit 87ca0f8680)
2025-05-01 14:48:46 -06:00
Andrew Trick
5643f53dca Merge pull request #81223 from atrick/62-missing-markdep
[6.2] Fix LifetimeDependenceInsertion: handle boxed indirect out arguments
2025-05-01 00:51:13 -07:00
Meghana Gupta
7b0ac8b5b6 Merge pull request #81216 from meg-gupta/fixcowcp
[6.2] Insert end_cow_mutation_addr for lifetime dependent values dependent on mutable addresses
2025-05-01 00:44:41 -07:00
Andrew Trick
1e0cec5065 Fix LifetimeDependenceInsertion: handle boxed indirect out arguments
Correctly generate dependency tracking for functions that return a non-Escapable
existential, such as:

func getMutableSpanWithOpaqueReturn(_ array: inout [Int]) -> any PAny & ~Copyable & ~Escapable

Previously, dependency insertion assumed that @out storage always initialized an
alloc_stack. But existentials are always boxed.

First, add a diagnostic to catch any missing dependency insertions now that
we're past the bootstrapping phase.

Then, generalize handling of dependency insertion to handle any access base as
long as it has a recognizable address source.

Fixes rdar://150388126 (Missing mark_dependence for opaque lifetime dependent
value)

(cherry picked from commit 9d8e8d3f05)
2025-04-30 16:55:55 -07:00
Meghana Gupta
ed3f6b4c35 Insert end_cow_mutation_addr for lifetime dependent values dependent on mutable addresses
Array/ArraySlice/ContiguousArray have support for mutableSpan property.
These types are "optimized COW" types, we use compiler builtins begin_cow_mutation/end_cow_mutation to
optimize uniqueness checks. Since mutableSpan is a property and not a coroutine there is
no way to schedule the end_cow_mutaton operation at the end of the access.
This can lead to miscompiles in rare cases where we can end up using a stale storage buffer after a cow.

This PR inserts end_cow_mutation_addr to avoid this issue.

Note: We can end up with unnecessary end_cow_mutation_addr. But it is just a barrier to prevent invalid optimizations
and has no impact.
2025-04-30 14:37:59 -07:00
Andrew Trick
6e19b06acc Fix LifetimeDependenceScopeFixup: extend scopes enclosing coroutines
When a coroutine is extended because of a dependent lifetime, extend all scopes
that enclose that coroutine even if the coroutine itself has no lifetime
dependencies.

Fixes rdar://150275147 (Invalid SIL after lifetime dependence fixup involving
coroutines)

(cherry picked from commit 4a65be8074)
2025-04-30 11:40:37 -07:00
Andrew Trick
7756a322fa LifetimeDependenceDiagnostics: note for unsupported closure capture
Add a note explaining that dependence on closure captures is not
supported. Otherwise, the diagnostics are very confusing:
"it depends on a closure capture; this is not yet supported"

(cherry picked from commit 83b0ce1098)
2025-04-30 00:09:40 -07:00
Andrew Trick
4c78ece643 LifetimeDependence: clarify diagnostics for many unusual cases.
Ensure that we always issue a diagnostic on error, but avoid emitting any notes that don't have source locations.

With implicit accessors and thunks, report the correct line number and indicate which accessor generates the error.

Always check for debug_value users.

Consistently handle access scopes across diagnostic analysis and diagnostic messages.

(cherry picked from commit ec512864eb)
2025-04-30 00:09:40 -07:00
Erik Eckstein
78bfc9f955 RedundantLoadElimination: support replacing a redundant copy_addr with a store
For example:
```
  %0 = load %1
  copy_addr %1 to %2
```
->
```
  %0 = load %1
  store %0 to %2
```

This is important for MandatoryRedundantLoadElimination to be able to create statically initialized globals in the mandatory pipeline.
For example:
```
public struct MyStruct {
  public static let r: Range<Int> = 1 ..< 3
}

```
gets a statically initialized global, even at Onone, with this improvement.

rdar://149356742
2025-04-28 08:01:49 +02:00
Andrew Trick
52ddb4d377 Bypass lifetime diagnostics in interfaces for copied arguments.
Briefly (April 2025), RawSpan._extracting, Span._extracting, and UTF8Span.span
returned a borrowed value that depended on a copied argument. Continue to
support those interfaces. The implementations were correct but needed an
explicit _overrideLifetime.

(cherry picked from commit 8a48cd979b)
2025-04-25 19:21:16 -07:00
Andrew Trick
5ddb6cebcc Fix LifetimeDependenceDiagnostics: scoped dependence on a copy
Diagnose a scoped dependence on an argument that inherits its lifetime as an
error:

@lifetime(borrow arg)
func reborrowSpan<T>(_ arg: Span<T>) -> Span<T> { arg }

@lifetime(copy span)
public func testBorrowInheritedArg<T>(_ span: Span<T>) -> Span<T> {
  reborrowSpan(span) // expected-error {{lifetime-dependent value escapes its scope}}
}

Fixes: rdar://146319009 ([nonescapable] enforce borrow constraint narrowing of inherited lifetime)
(cherry picked from commit 4f470a1d34)
2025-04-25 19:21:15 -07:00
Andrew Trick
805aaa3b66 Fix LifetimeDependenceDiagnostics: handle mark_dependence_addr
A small typo meant that scoped dependencies modeled with mark_dependence_addr
were not diagnosed.

(cherry picked from commit 92b2a8587f)
2025-04-25 19:21:15 -07:00
Andrew Trick
e04289abe2 LifetimeDependenceScopeFixup: cleanup for clarity
(cherry picked from commit bb9e52c3f2)
2025-04-25 19:21:15 -07:00
Andrew Trick
759d109a74 Fix LifetimeDependenceScopeFixup: read access can depend on 'inout'
Allow a dependency on a local [read] access scope to be transfered to the
caller's [modify] access.

Fixes rdar://149560133 (Invalid lifetime dependence error when
trying to return Span from an inout argument)

(cherry picked from commit 33fbe11bf8)
2025-04-22 12:33:01 -07:00
Andrew Trick
7df225e935 Merge pull request #80980 from atrick/62-rdar149397018-optional-return
[6.2] LifetimeDependenceScopeFixup: handle returning dependent Optional
2025-04-22 12:27:28 -07:00
Andrew Trick
161158806e LifetimeDependenceScopeFixup: handle returning dependent Optional
Add support for returnValue phis (e.g. to return an Optional .some or .none).

Fixes rdar://149397018 (Wrapping non escapable in an Optional
(or any copy lifetime wrapper) is an escape)

(cherry picked from commit a1aaed9159)
2025-04-21 22:57:06 -07:00
Meghana Gupta
2a314d0fab Handle a special case of borrowed from instruction in CopyToBorrowOptimization 2025-04-21 15:25:33 -07:00
Andrew Trick
a794a39a12 LifetimeDependenceScopeFixup: _read accessor: extend temporaries
Add support for extending owned temporary values in addition to access scopes
and borrow scopes. Required for _read accessors in which the coroutine depends
on an owned value.

(cherry picked from commit 62454f42fd)
2025-04-16 23:32:00 -07:00
Andrew Trick
5269c0c8e7 [NFC] Add LifetimeDependenceUseDefWalker utility.
Refactor VariableIntroducerUseDefWalker into a general
LifetimeDependenceUseDefWalker for use with LifetimeDependenceScopeFixup.

(cherry picked from commit b80bd16eea)
2025-04-16 23:23:55 -07:00
Andrew Trick
81ca8fd3ec Enable NonEscapableType support on Windows.
SwiftCompilerSources for Windows is now fully enabled, so there is no
longer any reason to gate these passes under an OS check.

commit d482ab73bc
Author: Hiroshi Yamauchi <hjyamauchi@gmail.com>
Date:   Fri Dec 13 09:24:44 2024 -0800

Update the pinned toolchain for Windows and enable SwiftCompilerSources for Win/ARM64
2025-03-31 11:21:06 -07:00
Andrew Trick
97b249bd11 Merge pull request #80263 from atrick/markdep-addr
SIL: add mark_dependence_addr
2025-03-26 10:33:42 -07:00
Erik Eckstein
8b2d27007f DiagnoseInfiniteRecursion: re-implement the pass in swift and fix a bug
Fixes a false alarm in case of recursive calls with different type parameters.
For example:

```
protocol P {
  associatedtype E: P
}

func noRecursionMismatchingTypeArgs1<T: P>(_ t: T.Type) {
  if T.self == Int.self {
    return
  }
  noRecursionMismatchingTypeArgs1(T.E.self)
}
```
2025-03-26 09:14:38 +01:00
Andrew Trick
d9dd93560d Support mark_dependence_addr in SIL passes. 2025-03-25 23:02:45 -07:00
Kuba Mracek
ed5e89a501 Also respect -mergeable-traps when merging cond_fails in SILOptimizer 2025-03-24 09:04:44 -07:00
Andrew Trick
001b162dc9 Surface addressableForDeps in SILType and FunctionConventions
With this approach, you cannot tell whether a parameter is addressable only
from the function type. Instead you need the SILValue that will be passed to the
call site.
2025-03-23 19:00:42 -07:00
Andrew Trick
bd7d3ec915 LifetimeDependentInsertion: assert on non-inout parameter dependency
The will be supported in a future commit that adds mark_dependence_addr.
2025-03-19 11:57:53 -07:00
Erik Eckstein
d52f7d1619 AST/SIL: Refactor and simplify AST.Type, AST.CanonicalType and SIL.Type
* let `SIL.Type` conform to `TypeProperties` to share the implementation of common type properties between the AST types and `SIL.Type`
* call references to an `AST.Type` `rawType` (instead of just `type`)
* remove unneeded stuff
* add comments
2025-03-14 09:40:22 +01:00
Meghana Gupta
b6b4a7bfdb Merge pull request #79841 from meg-gupta/fixsemanticarc
Fix two optimizer issues
2025-03-07 19:45:00 -08:00
Meghana Gupta
cd684a3200 Bailout of DestroyHoisting if there were no hoistable destroys
Otherwise, DestroyHoisting attemps to compute interior liveness
and inserts destoys at the ends. CanonicalizeOSSALifetimes is
designed to do this and not DestroyHoisting.
2025-03-07 10:40:42 -08:00
Meghana Gupta
87dcb65b4a Fix copy-to-borrow optimization's end_borrow insertion
allLifetimeEndingInstructions collects insertion points for end_borrows,
and can end up having duplicate entries in the case of enums with non payloaded cases.

Unique the entries so we don't end up with multiple end_borrows

Fixes rdar://146212574
2025-03-06 11:53:38 -08:00
Andrew Trick
b3f401d346 LifetimeDependenceScopeFixup: handle indirect yields & fix bugs
Handle coroutines that yield an address. Fix bugs involving extension of
multiple nested scopes that depend on multiple coroutine operands.
2025-03-05 02:12:21 -08:00
Andrew Trick
fa64a362a2 Add -Xfrontend -enable-address-dependencies
Temporary option to bootstrap '@'_addressable enforcement.

Once all the SILGen cases are handled, we won't need this option.
2025-03-03 16:21:48 -08:00
Andrew Trick
1b51aa8829 LifetimeDependenceScopeFixup: extend store_borrow scopes
This is require to handle '@'_addressable arguments on the caller side.
2025-03-03 16:21:48 -08:00
Andrew Trick
af878cc9af LifetimeDependenceInsertion: support '@'_addressable parameters 2025-03-03 11:56:37 -08:00
Andrew Trick
bc6200e592 SwiftCompilerSources: bridge '@'_addressable dependencies 2025-03-03 11:56:37 -08:00
Andrew Trick
e280c52825 Fix DestroyHoisting: don't ignore pointer escapes.
A pointer escape means the liveness is incomplete. Don't hoist destroys with
incomplete liveness.
2025-02-26 02:13:05 -08:00