<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">
<br class="">
<div><br class="">
<blockquote type="cite" class="">
<div class="">On Jan 18, 2021, at 4:09 PM, Johannes Doerfert <<a href="mailto:johannesdoerfert@gmail.com" class="">johannesdoerfert@gmail.com</a>> wrote:</div>
<br class="Apple-interchange-newline">
<div class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">On
 1/12/21 8:41 PM, Artur Pilipenko wrote:</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<blockquote type="cite" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<blockquote type="cite" class="">On Jan 11, 2021, at 9:44 PM, Johannes Doerfert<<a href="mailto:johannesdoerfert@gmail.com" class="">johannesdoerfert@gmail.com</a>>  wrote:<br class="">
<br class="">
The email formatting is somewhat broken. Might be my client.<br class="">
I try to answer inline, if I missed something or there is any other problem, let me know.<br class="">
<br class="">
<br class="">
On 1/11/21 6:39 PM, Artur Pilipenko wrote:<br class="">
<blockquote type="cite" class="">On Jan 11, 2021, at 3:46 PM, Johannes Doerfert <<a href="mailto:johannesdoerfert@gmail.com" class="">johannesdoerfert@gmail.com</a><<a href="mailto:johannesdoerfert@gmail.com" class="">mailto:johannesdoerfert@gmail.com</a>>>
 wrote:<br class="">
<br class="">
<br class="">
On 1/11/21 5:13 PM, Artur Pilipenko wrote:<br class="">
<br class="">
On Jan 11, 2021, at 2:40 PM, Johannes Doerfert <<a href="mailto:johannesdoerfert@gmail.com" class="">johannesdoerfert@gmail.com</a><<a href="mailto:johannesdoerfert@gmail.com" class="">mailto:johannesdoerfert@gmail.com</a>>> wrote:<br class="">
<br class="">
Hi Artur,<br class="">
<br class="">
On 1/11/21 4:25 PM, Artur Pilipenko wrote:<br class="">
I'm a bit confused with nocapture_use. I guess you need this because without it BasicAA would assume that the pointer is not accessed by the call at all.<br class="">
Correct.<br class="">
<br class="">
<br class="">
 So, as a workaround you introduce a use which implicitly reads and writes.<br class="">
Correct, for now. We could add "readonly"/"writeonly" etc. later on.<br class="">
<br class="">
<br class="">
But this might be a more general problem. For example:<br class="">
<br class="">
a = new ...<br class="">
store a, ptr, !nocapture<br class="">
a' = load ptr<br class="">
; Now you have 2 pointers to the same object (a' and a ) which BasicAA considers as no aliasing.<br class="">
v1 = load a<br class="">
store 5, a'<br class="">
v2 = load a<br class="">
<br class="">
We would happily replace v2 with v1 even though the memory was clobbered by the store through a’.<br class="">
Right. But that is not strictly speaking a problem. You can build things with the annotation<br class="">
that are nonsensical, though, that is nothing new. Especially if you employ the annotations<br class="">
alone you might not find a good use case, <a href="seehttps://reviews.llvm.org/D93189#2485826" class="">
seehttps://reviews.llvm.org/D93189#2485826</a>  .<br class="">
My concern here is that we miscompile a program which is seemingly correct. None of the users<br class="">
of pointer a escape the pointer. So, I assume it should be correct to mark the store as !nocapture.<br class="">
<br class="">
It looks like you assume a more restrictive definition for !nocapture. The proposed lang ref says:<br class="">
"``!nocapture`` metadata on the instruction tells the optimizer that the pointer<br class="">
stored is not captured in the sense that all uses of the pointer are explicitly<br class="">
marked otherwise”<br class="">
<br class="">
a) What do you mean by "uses of the pointer” here? Is it uses of the pointer value stored by the<br class="">
Annotated instruction? Is it uses of the memory modified by the store?<br class="">
<br class="">
It is uses of the stored pointer. So if you never load the pointer from the location<br class="">
you stored it using `!nocapture`, there are no uses and "all uses" are explicitly<br class="">
marked. If you do load it, you should make sure the use is "explicitly marked otherwise"<br class="">
because you do not get a "dependence edge" from the `store %a %ptr !nocapture` to `%a' = load %ptr`.<br class="">
In your example, that explicit use is missing. So you load `ptr` but that instruction is<br class="">
not annotated with an explicit use of `a`. Now, this could actually be OK, depending on the use,<br class="">
but unlikely what you want.<br class="">
<br class="">
If we would have operand bundles on loads you could do: `%a' = load %ptr ["nocapture_use"(%a)]`,<br class="">
which would correspond to the intended use `call @f(%ptr) ["nocapture_use"(%a)]`. That way you would<br class="">
be able to communicate `%a` through memory (here `%ptr`) without causing it to be captured.<br class="">
(This assumes you ensured `%a'` is not captured.)<br class="">
<br class="">
I think we could require `!nocapture` to be used with "nocapture_use" but I resisted so far<br class="">
as it would be more complex.<br class="">
On the other hand, it would make it clear that usage of only one of them is, so far,<br class="">
discouraged since it can easily lead to unexpected results.<br class="">
So, basically every use of the value loaded from memory which was previously stored to as !nocapture<br class="">
needs to have an annotation indicating that this is an alias of the original pointer.<br class="">
</blockquote>
Not necessarily an alias but a use of the original pointer. More below.<br class="">
</blockquote>
In general case we might have a pointer which is not the original pointer but an alias for it.<br class="">
<br class="">
E.g. a select between the original pointer and some other value:<br class="">
a = new ...<br class="">
store a, ptr, !nocapture<br class="">
a' = load ptr<br class="">
s = select c, a', some other ptr<br class="">
v1 = load s<br class="">
<br class="">
Or a derived pointer based off the original pointer:<br class="">
a = new ...<br class="">
store a, ptr, !nocapture<br class="">
a' = load ptr<br class="">
gep = gep a', offset<br class="">
v1 = load get<br class="">
<blockquote type="cite" class="">
<blockquote type="cite" class="">Do we need to annotate things like geps/bitcasts?<br class="">
<br class="">
What if the use is a phi or a select?<br class="">
a = new ...<br class="">
store a, ptr, !nocapture<br class="">
a' = load ptr<br class="">
s = select c, a', some other ptr ; do we annotate the select?<br class="">
v1 = load s ; or this load?<br class="">
<br class="">
It looks like currently we don’t have the means to annotate the uses of the loaded value. We might<br class="">
need to prohibit loads of !nocapture-stored values altogether (if this is a load in the same function as<br class="">
the nocapture store).<br class="">
</blockquote>
Right, we could do that.<br class="">
<br class="">
<br class="">
<blockquote type="cite" class="">b) Does the example above violate this statement somehow?<br class="">
<br class="">
So far, there is no violation per se possible. The semantics cannot be violated,<br class="">
as stated right now. Using the annotation changes the program semantic, if that change is not<br class="">
what you wanted, that is a problem but not a miscompile (IMHO).<br class="">
The way I’m looking at this is I have a program without !nocapture metadata and operand bundles<br class="">
and I want to derive it using some analysis.<br class="">
(We actually have an escape analysis capable of handling object graphs.<br class="">
<a href="https://llvm.org/devmtg/2020-09/slides/Pilipenko-Falcon-EA-LLVM-Dev-Mtg.pdf" class="">https://llvm.org/devmtg/2020-09/slides/Pilipenko-Falcon-EA-LLVM-Dev-Mtg.pdf</a><br class="">
https://www.youtube.com/watch?v=WHiU2-h_kRM<br class="">
We are looking into ways we can communicate facts this analysis computes with the rest of the<br class="">
optimizer. But we were looking into noalias and alias.scope metadata for such purpose.)<br class="">
So, I don’t want to change the behavior using the metadata, I want to derive it and for that I need<br class="">
to understand the semantic it implies.<br class="">
<br class="">
BTW, in your motivating example, what are the benefits you expect from the nocapture property?<br class="">
</blockquote>
You can mark the pointers in the caller nocapture, with all the benefits that might bring.<br class="">
For a more direct example, see this thread:<a href="https://lists.llvm.org/pipermail/cfe-dev/2020-December/067346.html" class="">https://lists.llvm.org/pipermail/cfe-dev/2020-December/067346.html</a><br class="">
Basically, we pass a bunch of pointers to an API. Since we need to pass an unknown number, we<br class="">
do it with an array of void* and a size. The runtime will only load the pointers and not cause<br class="">
them to escape, though it looks like they could. The same problem appears for memory latency hiding<br class="">
when you do an OpenMP target map, basically a bulk device memcpy. Since you do more than one, you<br class="">
pass a bunch of pointers via a void* array, which causes them to escape. This causes spurious aliases<br class="">
that we know cannot exist, though the runtime is not (supposed to be) linked statically and you need<br class="">
domain knowledge to deal with this. I split the OpenMP usage code from the patch but the initial version<br class="">
still had it:<a href="https://reviews.llvm.org/D93189?id=311479" class="">https://reviews.llvm.org/D93189?id=311479</a>  I'll clean it up and put it on phab again soon.<br class="">
</blockquote>
In general we want to have a way to express the results of some more powerful escape analysis in the IR<br class="">
so CaptureTracking/BasicAA can take advantage of this analysis. In your case this analysis is some domain<br class="">
specific knowledge, in our case it is a downstream analysis pass.<br class="">
<br class="">
We can easily express basic facts like capture/nocapture using attributes and metadata. Things get more<br class="">
difficult when we need to express aliasing properties. For example, your case when the call modifies an<br class="">
otherwise unescaped pointer. While the proposed solution works for the motivational example, I’m afraid<br class="">
it’s not really extensible for the general case.<br class="">
<br class="">
First, we would need to have the ability to attach operand bundles to instructions of any kind. Second, there<br class="">
are open questions, like how do we treat uses which are not a memory operations? How do we deal with<br class="">
aliases? These things are not addressed in the current proposal.<br class="">
<br class="">
The best idea I had so far regarding expressing the results of our EA in the IR was to use noalias and<br class="">
alias.scope metadata. Essentially every unescaped object can be assigned to a separate scope and every<br class="">
memory operation can be marked as noalias wrt the scopes we know it doesn’t touch.<br class="">
<br class="">
In fact, the scheme you propose where every user of a !nocapture pointer is annotated with the original<br class="">
pointer resembles the alias scopes and noalias metadata. The difference is alias scopes and noalias use<br class="">
Indirection through metadata while your proposal relies on operand bundles to directly link the original<br class="">
pointer.<br class="">
<br class="">
Do you think you can apply something like this to you problem?<br class="">
</blockquote>
<br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">There
 is a fundamental difference with the proposal here and alias scopes that is not</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">"indirection
 through metadata". `!nocapture` + `"nocapture_use"` are independent of the</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">surrounding.
 This is crucial because it avoids the scaling problem that comes with the</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">bidirectional
 approach of `noalias.scopes` + `!noalias` metadata. As part of the Fortran</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">alias
 discussions and the AA monthly working group, we have seen how problematic large</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">amounts
 of `noalias` metadata can be. You basically start listing edges in your</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">alias/dependence
 graph at some point. </span></div>
</blockquote>
<div>It sounds like it's a matter of representation. Conceptually in both cases we are explicitly providing external </div>
<div>aliasing facts. Note that with the proposed `!nocapture` + `"nocapture_use”` scheme every user of a <font color="#000000" class="">`!nocapture`</font></div>
<div><font color="#000000" class="">stored pointer </font><span style="color: rgb(0, 0, 0);" class="">needs </span><span style="color: rgb(0, 0, 0); caret-color: rgb(0, 0, 0);" class="">to be annotated.</span></div>
<br class="">
<blockquote type="cite" class="">
<div class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">We
 are looking at alternative solutions but those</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">are
 so far unrelated to he use case that is discussed here.</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<blockquote type="cite" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<blockquote type="cite" class="">Given an escape analysis you might be interested in the same use case. A pointer is stored but you can<br class="">
see from the uses of the stored-to location that it does not escape. As you pointed out, if those uses<br class="">
are non-calls we cannot attach "nocapture_use" for now, which is a problem. On the other hand, if they<br class="">
are in the same function, we could forward the pointer and eliminate the load, or the memory is already<br class="">
aliasing something and it is unclear how much we can deduce anyway.<br class="">
</blockquote>
The unfortunately property of this approach is that we can’t simply compute the analysis and annotate the<br class="">
IR with the results. First we need to shape the IR in the way so we can attach the results of the analysis.<br class="">
This kind of shaping (store load forwarding to eliminate extra aliases) may require the results of this analysis<br class="">
itself (this is assuming we want to reuse some of the existing LLVM transforms to do store load forwarding).<br class="">
</blockquote>
<br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">You
 seem to argue this approach is not a good fit for your analysis, which I agree. That seems</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">to
 be not a problem on its own. </span>Do you have an alternative proposal that would subsume this</div>
</blockquote>
<blockquote type="cite" class="">
<div class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">approach?</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
</div>
</blockquote>
<div>To me the fact that you need to annonate every single user of a `!nocapture` stored pointer looks like the most </div>
<div>fragile part of the proposal. It makes it hard to generalize this scheme. It makes it easy to misuse this scheme, </div>
<div>both for the frontends and for the optimizer. Moreover, current wording of the proposal doesn't address these </div>
<div>issues.</div>
<div><br class="">
</div>
<div>
<div>How far can we get with an approach which is conservatively correct without explicit `"nocapture_use”` </div>
<div>annotations? </div>
<div><br class="">
</div>
<div>Currently there are 2 places where BasicAA uses isNonEscapingLocalObject: </div>
<div>* Aliasing between isNonEscapingLocalObject and isEscapeSource</div>
<div><a href="https://github.com/llvm/llvm-project/blob/main/llvm/lib/Analysis/BasicAliasAnalysis.cpp#L1563" class="">https://github.com/llvm/llvm-project/blob/main/llvm/lib/Analysis/BasicAliasAnalysis.cpp#L1563</a></div>
<div>* ModRef for a isNonEscapingLocalObject and a call</div>
<div><a href="https://github.com/llvm/llvm-project/blob/main/llvm/lib/Analysis/BasicAliasAnalysis.cpp#L839" class="">https://github.com/llvm/llvm-project/blob/main/llvm/lib/Analysis/BasicAliasAnalysis.cpp#L839</a></div>
<div><br class="">
</div>
<div>If we were to support nocapture stores without explicit `"nocapture_use”` annotations we would need to </div>
<div>differentiate between isNonEscapingLocalObject with StoreCaptures==true and StoreCaptures==false. </div>
<div>These are two different properties and we would need to handle them separately. </div>
<div><br class="">
</div>
<div>For the aliasing between isNonEscapingLocalObject and isEscapeSource we would need to change </div>
<div>isEscapeSource for isNonEscapingLocalObject(StoreCaptures==false) case. Specifically, if StoreCaptures==false </div>
<div>then isEscapeSource should not consider loads as escape sources.</div>
<div><br class="">
</div>
<div>For the ModRef query around calls it's more compilcated. The easiest thing to do here is to not use </div>
<div>isNonEscapingLocalObject(StoreCaptures==false). I don't know if this is too limiting for your example. </div>
<div>But we can come up with some analysis here as well. What we need to know is the fact that a call doesn’t </div>
<div>capture pointers reachable through its arguments. This would require a new argument attribute, something </div>
<div>like nocapture_content.</div>
<div><br class="">
</div>
<div>My next comment is only somewhat related to `"nocapture_use”` issue. Your current proposal marks stores</div>
<div>as `!nocapture`. But I assume that the store can be marked as nocapture because the underlying object is </div>
<div>unescaped. Why don't we mark this fact instead? If we have this fact then any store to an unescaped memory </div>
<div>can be treated as nocapture (assuming we are doing conservatively correct analysis for StoreCaptures==false). </div>
<div>This will give us a useful fact about the underlying object as well (it can be used for things other than aliasing).  </div>
<div><br class="">
</div>
<div>There is a caveat to this suggestion. The proposed `!nocapture` metadata makes it possible to express </div>
<div>flow-sensitive facts (a store into the same underlying object might be nocapture on one path, but capture on some </div>
<div>other). We would give up this flow-sensitivity if we make the underlying object instead. On the other hand, global </div>
<div>property instead of a flow-sensitive propery will make it easier for a conservatively correct analysis.</div>
</div>
<div><br class="">
</div>
<blockquote type="cite" class="">
<div class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">Partially
 related: Maybe you want to give a short presentation in our next AA call about your</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">analysis
 and the ideas you have in this space:</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<a href="https://docs.google.com/document/d/1ybwEKDVtIbhIhK50qYtwKsL50K-NvB6LfuBsfepBZ9Y/edit?usp=sharing" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">https://docs.google.com/document/d/1ybwEKDVtIbhIhK50qYtwKsL50K-NvB6LfuBsfepBZ9Y/edit?usp=sharing</a><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
</div>
</blockquote>
I’ll plan to join.</div>
<div><br class="">
</div>
<div>Artur<br class="">
<blockquote type="cite" class="">
<div class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">~
 Johannes</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
<blockquote type="cite" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">
Artur<br class="">
<blockquote type="cite" class="">If we would want to use `!nocapture`<br class="">
more fine-grained we could try to come up with a way to tie it to a "nocapture_use", but that would<br class="">
certainly make it more complicated.<br class="">
~ Johannes<br class="">
<br class="">
<br class="">
<blockquote type="cite" class="">Artur<br class="">
<br class="">
<br class="">
<br class="">
Basically, what am I doing wrong that I get a miscompile on this example?<br class="">
<br class="">
You don't get the clobber because you did not explicitly mark the use of `%a` in `%a'`.<br class="">
<br class="">
WDYT?<br class="">
<br class="">
~ Johannes<br class="">
<br class="">
<br class="">
<br class="">
Artur<br class="">
<br class="">
Note that we do not inline a call with an "unkown" operand bundle, so there is no fear we<br class="">
accidentally produce such a situation as you pointed out. A "proper" version of the example<br class="">
would be:<br class="">
<br class="">
```<br class="">
a = new<br class="">
store a, ptr, !nocapture<br class="">
call foo(ptr, a) !nocapture_use(a)<br class="">
<br class="">
void foo(arg_ptr. arg_a) {<br class="">
  a' = load arg_ptr<br class="">
  v1 = load arg_a<br class="">
 ...<br class="">
}<br class="">
```<br class="">
which should be OK.<br class="">
<br class="">
Does that make sense?<br class="">
<br class="">
~ Johannes<br class="">
<br class="">
<br class="">
Artur<br class="">
<br class="">
On Jan 7, 2021, at 4:20 PM, Johannes Doerfert via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a><<a href="mailto:llvm-dev@lists.llvm.org" class="">mailto:llvm-dev@lists.llvm.org</a>>> wrote:<br class="">
<br class="">
TL;DR: A pointer stored in memory is not necessarily captured, let's add a way to express this.<br class="">
<br class="">
Phab:<a href="https://reviews.llvm.org/D93189" class="">https://reviews.llvm.org/D93189</a><br class="">
<br class="">
--- Commit Message / Rational ---<br class="">
<br class="">
Runtime functions, as well as regular functions, might require a pointer<br class="">
to be passed in memory even though the memory is simply a means to pass<br class="">
(multiple) arguments. That is, the indirection through memory is only<br class="">
used on the call edge and not otherwise relevant. However, such pointers<br class="">
are currently assumed to escape as soon as they are stored in memory<br class="">
even if the callee only reloads them and use them in a "non-escaping" way.<br class="">
Generally, storing a pointer might not cause it to escape if all "uses of<br class="">
the memory" it is stored to all have the "nocapture" property.<br class="">
<br class="">
To allow optimizations in the presence of pointers stored to memory we<br class="">
introduce two new IR extensions. `!nocapture` metadata on stores and<br class="">
"nocapture_use" operand bundles for call(base) instructions. The former<br class="">
ensures that the store can be ignored for the purpose of escape<br class="">
analysis. The latter indicates that a call is using a pointer value<br class="">
but not capturing it. This is important as the call might still read<br class="">
or write the pointer and since the passing of the pointer through<br class="">
memory is not considered "capturing" with the "nocapture" metadata,<br class="">
we need to otherwise indicate the potential read/write.<br class="">
<br class="">
As an example use case where we can deduce `!nocapture` metadata,<br class="">
consider the following code:<br class="">
<br class="">
```<br class="">
struct Payload {<br class="">
 int *a;<br class="">
 double *b;<br class="">
};<br class="">
<br class="">
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,<br class="">
                   void *(*start_routine) (void *), void *arg);<br class="">
<br class="">
int use(double);<br class="">
<br class="">
void fn(void *v) {<br class="">
 Payload *p = (Payload*)(v);<br class="">
 // Load the pointers from the payload and then dereference them,<br class="">
 // this will not capture the pointers.<br class="">
 int *a = p->a;<br class="">
 double *b = p->b;<br class="">
 *a = use(*b);<br class="">
}<br class="">
<br class="">
void foo(int *a, double *b) {<br class="">
 Payload p = {a, b};<br class="">
 pthread_create(..., &fn, &p);<br class="">
}<br class="">
```<br class="">
<br class="">
Given the usage of the payload struct in `fn` we can conclude neither<br class="">
`a` nor `b` in are captured in `foo`, however we could not express this<br class="">
fact "locally" before. That is, we can deduce and annotate it for the<br class="">
arguments `a` and `b` but only since there is no other use (later on).<br class="">
Similarly, if the callee would not be known, we were not able to<br class="">
describe the "nocapture" behavior of the API.<br class="">
<br class="">
A follow up patch will introduce `!nocapture` metadata to stores<br class="">
generated during OpenMP lowering. This will, among other things, fix<br class="">
PR48475. I generally expect us to find more APIs that could benefit from<br class="">
the annotation in addition to the deduction we can do if we see the callee.<br class="">
<br class="">
---<br class="">
<br class="">
As always, feedback is welcome. Feel free to look at the phab patch as well.<br class="">
<br class="">
Thanks,<br class="">
 Johannes<br class="">
<br class="">
<br class="">
--<br class="">
──────────<br class="">
∽ Johannes<br class="">
<br class="">
_______________________________________________<br class="">
LLVM Developers mailing list<br class="">
<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a><<a href="mailto:llvm-dev@lists.llvm.org" class="">mailto:llvm-dev@lists.llvm.org</a>><br class="">
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a></blockquote>
</blockquote>
</blockquote>
</div>
</blockquote>
</div>
<br class="">
</body>
</html>