[llvm] [llubi] Add support for captures (PR #201170)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 19 10:41:19 PDT 2026


dtcxzyw wrote:

> Also could you summarize what the semantics are now for the various provenance-related captures cases?

1. A copy of provenance will be created when the pointer argument has the capture attribute, if it doesn't capture all components the original one has.
2. The provenance copy is initialized with the same capability as the original one. After the function returns or unwinds, all provenances derived from the copy will be updated (not fully implemented yet)
3. This copy cannot be mixed with the original provenance (See https://github.com/llvm/llvm-project/pull/201170#issuecomment-4633060552), even if the pointer is identical. For example:
```
; we must create a copy here since we don't know whether %p is used in other places.
define ptr @identical(ptr captures(ret: address, provenance) %p1, ptr %p2) {
  ; Note 1: we cannot use %p1 and %p2 to construct a new pointer with a valid provenance
  ret ptr %p1
}

; %p is a pointer with provenance
%p1 = call @identical(ptr %p, ptr %p)
; Note 2: we cannot use %p1 and %p to construct a new pointer with a valid provenance
```

That is a bit weird... But I don't have a better idea :(

> An exception to this is inference of captures(ret: address, provenance), where we don't see uses after the return value. I think for that specific case we need to actually strip this provenance (i.e. recover the provenance it was derived from) when returning, so things will be consistent again at that point.

The current implementation doesn't respect this usage. But this should be doable. We can add another term: 
4. Specifically, if the pointer is captured through the return value and the components are not removed after return, it can recover the provenance of the original pointer.

With this adjustment, Note 2 in the example above becomes legal while Note 1 remains illegal.

I am still waiting for https://github.com/llvm/llvm-project/pull/200672. After it lands, you can see more detailed behavior of the interpreter from the tests.


https://github.com/llvm/llvm-project/pull/201170


More information about the llvm-commits mailing list