<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">On Wed, Feb 10, 2021 at 1:40 AM Johannes Doerfert <<a href="mailto:johannesdoerfert@gmail.com">johannesdoerfert@gmail.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">On 2/8/21 11:46 PM, Juneyoung Lee wrote:<br>
> Hi,<br>
><br>
> About syntactic constraints - I think it can be helpful for transformations<br>
> that need to be fully aware of all allocations' lifetimes.<br>
> For example, AddressSanitizer is currently simply giving up instrumenting<br>
> things if there is an unknown lifetime usage.<br>
> If all lifetime intrinsics' pointers are guaranteed to be known<br>
> expressions, this issue is resolved.<br>
<br>
It is "resolved" by disallowing more complex use cases. To hyperbolize<br>
an analogy: Constant propagation could avoid almost all of its <br>
checks/analysis<br>
if we restrict all expressions to be constant 0. I know this is not the same<br>
thing but I hope you see where I'm getting at. The proper solution for ASAN<br>
is to check if it can handle the lifetime markers and not utilize them <br>
otherwise.<br>
If they happen to fall in the proposed syntactic restrictions I assume ASAN<br>
can already handle them fine anyway, right?<br></blockquote><div><br></div><div>Yep, it falls back to the conservative mode.</div><div>But, I'm still in favor of explicitly giving a guideline describing what the pointer argument<br></div><div>of lifetime.start/end looks like; otherwise transformations that use lifetime should</div><div>speculate on their own about the shape of the pointer arguments.</div><div><br></div><div>What about starting with writing e.g., ValueTracking::isCanonicalLifetimeStart(IntrinsicInst *I) (and for lifetime.end as well),</div><div>that checks whether I is lifetime.start(p) where p is a known form?</div><div>p should be one of alloca / bitcast(alloca) / ... and anything that may appear during transformations in</div><div>O3 pipeline.</div><div>Passes can use this function if they want and get a guarantee that they are not missing any form</div><div>of lifetime that appears in the pipeline, which is great.</div><div>It is up to the pass whether it will crash or fallback to a conservative mode if isCanonicalLifetimeStart</div><div>returned false.</div><div><br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
><br>
> if (HasUntracedLifetimeIntrinsic) {<br>
> // If there are lifetime intrinsics which couldn't be traced back to an<br>
> // alloca, we may not know exactly when a variable enters scope, and<br>
> // therefore should "fail safe" by not poisoning them.<br>
> StaticAllocaPoisonCallVec.clear();<br>
> DynamicAllocaPoisonCallVec.clear();<br>
> }<br>
><br>
> Interestingly, AddressSanitizer is the one that raises an issue as well if<br>
> the syntactic restriction is enforced.<br>
> It replaces allocas with __asan_stack_malloc_N, but still leaves its<br>
> lifetime uses, which breaks the syntactic restriction. A possible solution<br>
> for this is to simply remove the lifetime calls.<br>
<br>
I can't stress this enough, syntactic restrictions are rarely helpful.<br>
Now we are talking about dropping information because of it. We seem<br>
to have also fond a non-stack memory user, great.<br>
<br>
~ Johannes<br><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><br></div><font size="1">Juneyoung Lee</font><div><font size="1">Software Foundation Lab, Seoul National University</font></div></div></div></div></div></div>