<div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jan 6, 2022 at 6:47 PM Johannes Doerfert <<a href="mailto:johannesdoerfert@gmail.com">johannesdoerfert@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
On 1/5/22 07:41, Nikita Popov wrote:<br>
>> Maybe I am confused but I thought something like this pseudo-code<br>
>> could be optimized, readonly_on_return is similar.<br>
>><br>
>> ```<br>
>> int a = 42;<br>
>> invoke foo(/* readonly_on_unwind */ &a);<br>
>> lp:<br>
>>     return a; // a == 42<br>
>> cont:<br>
>>     return a; // a unknown<br>
>> ```<br>
>><br>
> Okay, I guess there's a possible point of confusion here: The intention<br>
> here is that the attribute encodes a requirement on accesses *after* the<br>
> call. readonly_on_unwind would allow only reading "a" in "lp", but does not<br>
> prevent foo() from modifying "a" even if it ultimately unwinds. With that<br>
> in mind, I don't think the attribute would enable any additional<br>
> optimization here.<br>
><br>
> So maybe the proposed attribute is better named as "noreadafterunwind"<br>
> rather than "noreadonunwind".<br>
<br>
So I misunderstood the entire idea :D<br>
<br>
I am not sure how I feel about such a new "category" of attributes.<br>
Can we try to throw around some ideas before we commit to it?<br>
<br>
One of the weirdest things is that the semantics are somewhat<br>
described in terms of the caller. Making it callee-centric might<br>
help, e.g., `poison_on_unwind(%a)` to indicate the value in the<br>
unwind case is "not read" or rather, replaced with poison.<br></blockquote><div><br></div><div>Yeah, the caller-dependent semantics are unusual. poison_on_unwind is an interesting idea, though also a bit odd in that attributes usually describe a constraint.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

You noted in the other mail that we don't want to make unwind paths<br>
explicit (which I agree with, FWIW). However, in the caller we already<br>
have them explicitly, no? So what materializing the "virtual memset"/<br>
lifetime.end stuff there? Frontends (like Rust) can do it based on the<br>
callee type so that should not be a problem.<br></blockquote><div><br></div><div>We need the information in the callee though, so that optimizations that reason about unwinds (DSE, MemCpyOpt, LICM etc) running on the callee can benefit. They wouldn't have information about what is going on in the caller (apart from what we can provide via function attributes).</div><div><br></div><div>At this point I'm starting to lean towards not introducing a separate attribute for this, and only tweaking sret semantics to specify it can't be read on unwind. That's the original motivation, and I'm not sure solving something more general is really worthwhile, as this turned out to be trickier than I expected.<br></div><div><br></div><div>For the Rust move arguments, I think that the proper modeling is likely a stronger form of "noalias" rather than this kind of noreadafterunwind/noreadafterreturn attributes. Normally, "noalias" only means that it is noalias for the duration of the call. Rust move arguments remain "noalias" after the call. That is, even after we return or unwind, accesses to the memory can only happen through pointers based on the original noalias argument (which would have to be captured at that point). I just realized that this is similar (the same?) as the semantics for "noalias" on return values, which is not the same as "noalias" on arguments. Not sure what to call this concept though. really_noalias :)</div><div><br></div><div>Regards,</div><div>Nikita<br></div></div></div>