# Progress on Opaque SIL Values

**URL:** <https://forums.swift.org/t/progress-on-opaque-sil-values/88589>\
**Category:** Compiler\
**Created:** [July 27, 2026, 10:10pm UTC](https://forums.swift.org/t/progress-on-opaque-sil-values/88589 "2026-07-27T22:10:33Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![kavon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kavon/32/9774_2.png) [@kavon](https://forums.swift.org/u/kavon)\
**Post date:** [July 27, 2026, 10:10pm UTC](https://forums.swift.org/t/progress-on-opaque-sil-values/88589/1 "2026-07-27T22:10:34Z")

</div>

Hi everyone,

SIL opaque values (`-enable-sil-opaque-values`) is a compiler infrastructure project that defers the lowering of resilient and generic types to addresses, until the `AddressLowering` pass, so they are treated like loadable SSA values for better optimization. It's an idea proposed **nearly 10 years ago (!)** in [Proposal: Opaque SIL values](https://forums.swift.org/t/proposal-opaque-sil-values/4971) . I'll defer to the [original proposal](https://gist.github.com/atrick/38063a90bf4a6ebae05fe83ea9ebc0b7) for an overview and additional motivation, as it is still true today.

The first stage of this project has been to make SILGen fully compatible with SIL opaque values and run `AddressLowering` soon after SILGen. This would allow us to have `-enable-sil-opaque-values` on by default and set us up to unlock the first of several benefits of this project: simplify SILGen.

Many people over the years have put in work to get that first stage done. Unfortunately, every time we have reached a milestone in terms of full functionality, such as building the standard library cleanly, _we've regressed_.

Progress is lost primarily from new contributions to SILGen or SIL that are not tested under SIL Opaque Values. So, I'd like to ask everyone to please test your changes under `-enable-sil-opaque-values` too:

- For a non-executable test doing `-emit-sil` , `-emit-ir` or later: Add a `RUN` line with `-enable-sil-opaque-values` . That covers both SILGen and AddressLowering compatibility.
  - If you have separate SILGen and SIL test files, you can test just SILGen under opaque values with `-emit-silgen-ossa -enable-sil-opaque-values` , which goes a bit further than `-emit-silgen` to reach verified SIL, but without running any diagnostic or mandatory passes.

- For a test using `%target-run-simple-swift`, we have a build target `check-swift-optimize_none_with_opaque_values` that will compile and run your test under `-enable-sil-opaque-values`.
- Tests that only go up to `-typecheck` or an earlier stage of the compiler don't need additional testing.

In an effort to prevent further backsliding as work continues on opaque values, I plan to increase the amount of testing and usage of it:

- Specific sub-targets of the standard library will start building with the flag enabled. So far, we have `swift-backtrace` [using](https://github.com/swiftlang/swift/pull/90147) it and I'm eyeing Volatile, RegexParser, RegexBuilder, and Distributed next.
- I've started auditing and automatically updating tests to have an additional RUN line exercising opaque values.
- CI will start [running the execution tests](https://github.com/swiftlang/swift/pull/90903) under opaque values. This will mean you won't need a second RUN line if your test is using `%target-run-simple-swift`

Here are some guidelines while working on new code in SILGen:

- Rely on `SILFunctionConventions` to determine whether an argument or result of a function is transferred indirectly (i.e., as an address) or directly as an SSA value.
- Avoid using `TypeLowering::isAddressOnly()` , as it will give only the fixed, post-AddressLowering answer, which is wrong in SILGen under opaque values. I'm working to make that API unavailable within SILGen with [this PR](https://github.com/swiftlang/swift/pull/90972) and introducing `isLoadableOrOpaque`.
- Much of what is backing opaque values today in the compiler relies upon the `SILAddressConventions` type and the `AddressLowering` pass, so they're worth a read.

---

<div class="post-metadata">

**Author:** ![kavon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kavon/32/9774_2.png) [@kavon](https://forums.swift.org/u/kavon)\
**Post date:** [August 24, 2026, 6:20pm UTC](https://forums.swift.org/t/progress-on-opaque-sil-values/88589/2 "2026-08-24T18:20:09Z")

</div>

I'd like to highlight a point I made in this initial post. If you're adding a new `executable_test`, we run the test both with and without `-enable-sil-opaque-values` in CI as of [this change](https://github.com/swiftlang/swift/pull/90903). So it's important to look in the CI logs for the run configuration under which a failure has occurred. For example, in the current [macOS x86\_64 smoke test bot](https://ci.swift.org/job/swift-PR-macos-smoke-test/)'s logs, you can look for the following strings right after the testing summary:

- `check-swift-validation-macosx-x86_64 finished` =\> Regular Run
- `check-swift-validation-optimize_none_with_opaque_values-macosx-x86_64` =\>Opaque Values Run

> The intention behind the additional run is to remind people who are adding new features/changes **to the compiler** that their work should strive to be compatible with opaque values.

If you run into a failure only under the opaque values run, please check to see whether it is related to your compiler changes. You can run the build target `check-swift-optimize_none_with_opaque_values` locally to reproduce the CI failure. For example, if say AddressLowering or SILGen is crashing on your new SIL instruction, then you should add opaque values support for it in your PR.

If after investigating, you see it is a pre-existing issue or unrelated to your changes, please keep your test as-is and simply add `// XFAIL: swift_test_mode_optimize_none_with_opaque_values` . This is the preferred action, marking it as "to be fixed" under that run. An `XFAIL` keeps it running in CI under opaque values, helping those working on it know the impact of their bug fix if they cause your test to unexpectedly pass. When that does happen, it signals that there is already some test coverage available, helping avoid redundant test additions. Plus, a fix can sometimes untangle issues for an unrelated language feature, and it's good to have free test coverage for that turned on by simply removing the `XFAIL`.
