<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>I think this is an interesting problem.</p>
<p>I'd probably lean towards the use of a separate attribute, but
not strongly so.</p>
<p>The example which makes me prefer the separate attribute would be
a function with an out-param. It's very unlikely that an
out-param will be read on the exception path. Being able to
perform DSE for such out params seems quite interesting.</p>
<p>However, I'll note that the same problem can be framed as an
escape problem. That is, we have an annotation not that a value
is dead on the exception path, but that it hasn't been captured on
entry to the routine. Then, we can apply local reasoning to show
that the first store can't be visible to may_unwind, and eliminate
it. <br>
</p>
<p>I'd want to give the escape framing more thought as that seems
potentially more general. Does knowing that an argument does not
point to escaped memory on entry help on all of your motivating
examples?</p>
<p>Philip<br>
</p>
<div class="moz-cite-prefix">On 12/4/21 2:39 AM, Nikita Popov via
llvm-dev wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CAF+90c9cub-W6wBhzYZ3mKfhWZWXhqYbb19vbrWXnkGtusy8Lg@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div dir="ltr">
<div>Hi,</div>
<div><br>
</div>
<div>Consider the following IR:</div>
<div><br>
</div>
<div>declare void <a class="gmail_plusreply"
id="plusReplyChip-4" moz-do-not-send="true">@may_unwind()</a><br>
</div>
<div>define void @test(i32* noalias sret(i32) %out) {</div>
<div> store i32 0, i32* %out</div>
<div> call void <a class="gmail_plusreply"
id="plusReplyChip-3" moz-do-not-send="true">@may_unwind()<br>
</a>
<div> store i32 1, i32* %out</div>
</div>
<div> ret void<br>
</div>
<div>}</div>
<div><br>
</div>
<div>Currently, we can't remove the first store as dead, because
the @may_unwind() call may unwind, and the caller might read
%out at that point, making the first store visible.</div>
<div><br>
</div>
<div>Similarly, it prevents call slot optimization in the
following example, because the call may unwind and make an
early write to the sret argument visible:<br>
</div>
<br>
declare void @may_unwind(i32*)<br>
declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)<br>
define void @test(i32* noalias sret(i32) %arg) {<br>
%tmp = alloca i32<br>
call void @may_unwind(i32* nocapture %tmp)<br>
%tmp.8 = bitcast i32* %tmp to i8*<br>
%arg.8 = bitcast i32* %arg to i8*<br>
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %arg.8, i8*
align 4 %tmp.8, i64 4, i1 false)<br>
ret void<br>
<div>}</div>
<div><br>
</div>
<div>I would like to address this in some form. The easiest way
would be to change LangRef to specify that sret arguments
cannot be read on unwind paths. I think that matches how sret
arguments are generally used.</div>
<div><br>
</div>
<div>Alternatively, this could be handled using a separate
attribute that can be applied to any argument, something along
the lines of "i32* nounwindread sret(i32) %arg". The benefit
would be that this is decoupled from sret ABI semantics and
could potentially be inferred (e.g. if the function is only
ever used with call and not invoke, this should be a given).</div>
<div><br>
</div>
<div>Any thoughts on this? Is this a problem worth solving, and
if yes, would a new attribute be preferred over restricting
sret semantics?<br>
</div>
<div><br>
</div>
<div>Regards,</div>
<div>Nikita<br>
</div>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<pre class="moz-quote-pre" wrap="">_______________________________________________
LLVM Developers mailing list
<a class="moz-txt-link-abbreviated" href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>
</pre>
</blockquote>
</body>
</html>