<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 11, 2021, at 3:46 PM, Johannes Doerfert <<a href="mailto:johannesdoerfert@gmail.com" class="">johannesdoerfert@gmail.com</a>> wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<div class=""><br class="">
On 1/11/21 5:13 PM, Artur Pilipenko wrote:<br class="">
<blockquote type="cite" class=""><br class="">
<blockquote type="cite" class="">On Jan 11, 2021, at 2:40 PM, Johannes Doerfert <<a href="mailto:johannesdoerfert@gmail.com" class="">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="">
<blockquote type="cite" 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="">
</blockquote>
Correct.<br class="">
<br class="">
<br class="">
<blockquote type="cite" class=""> So, as a workaround you introduce a use which implicitly reads and writes.<br class="">
</blockquote>
Correct, for now. We could add "readonly"/"writeonly" etc. later on.<br class="">
<br class="">
<br class="">
<blockquote type="cite" 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="">
</blockquote>
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, see <a href="https://reviews.llvm.org/D93189#2485826" class="">
https://reviews.llvm.org/D93189#2485826</a> .<br class="">
</blockquote>
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="">
</blockquote>
<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="">
</div>
</div>
</blockquote>
So, basically every use of the value loaded from memory which was previously stored to as !nocapture </div>
<div>needs to have an annotation indicating that this is an alias of the original pointer.</div>
<div><br class="">
</div>
<div>Do we need to annotate things like geps/bitcasts? </div>
<div><br class="">
</div>
<div>What if the use is a phi or a select?</div>
<div>
<div>a = new ...</div>
<div>store a, ptr, !nocapture</div>
<div>a' = load ptr</div>
<div>s = select c, a', some other ptr ; do we annotate the select?</div>
<div>v1 = load s ; or this load?</div>
<div><br class="">
</div>
<div>It looks like currently we don’t have the means to annotate the uses of the loaded value. We might </div>
<div>need to prohibit loads of !nocapture-stored values altogether (if this is a load in the same function as </div>
<div>the nocapture store). </div>
</div>
<div>
<blockquote type="cite" class="">
<div class="">
<div class=""><br class="">
<br class="">
<blockquote type="cite" class="">b) Does the example above violate this statement somehow?<br class="">
</blockquote>
<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="">
</div>
</div>
</blockquote>
The way I’m looking at this is I have a program without !nocapture metadata and operand bundles</div>
<div>and I want to derive it using some analysis.</div>
<div>(We actually have an escape analysis capable of handling object graphs. </div>
<div><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></div>
<div><a href="https://www.youtube.com/watch?v=WHiU2-h_kRM" class="">https://www.youtube.com/watch?v=WHiU2-h_kRM</a></div>
<div>We are looking into ways we can communicate facts this analysis computes with the rest of the </div>
<div>optimizer. But we were looking into noalias and alias.scope metadata for such purpose.)</div>
<div>So, I don’t want to change the behavior using the metadata, I want to derive it and for that I need</div>
<div>to understand the semantic it implies. </div>
<div><br class="">
</div>
<div>BTW, in your motivating example, what are the benefits you expect from the nocapture property?</div>
<div><br class="">
</div>
<div>Artur</div>
<div>
<blockquote type="cite" class="">
<div class="">
<div class=""><br class="">
<br class="">
<blockquote type="cite" class=""><br class="">
Basically, what am I doing wrong that I get a miscompile on this example?<br class="">
</blockquote>
<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?</div>
</div>
</blockquote>
</div>
<div>
<blockquote type="cite" class="">
<div class="">
<div class=""><br class="">
~ Johannes<br class="">
<br class="">
<br class="">
<blockquote type="cite" class=""><br class="">
Artur<br class="">
<br class="">
<blockquote type="cite" 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="">
<blockquote type="cite" class="">Artur<br class="">
<br class="">
<blockquote type="cite" 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>> 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><br class="">
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev<br class="">
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</div>
</div>
</blockquote>
</div>
<br class="">
</body>
</html>