<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>I ran across something a bit similar, and thought I'd share the
      case for purposes of idea generation.  <br>
    </p>
    <p>For a function w/out-params, it's common to have cases where the
      out-params are not actually used by the callee.  I've recently
      been making some improvements for the cases where the out-param is
      the only thing holding the call live (D115829), but if we actually
      use the return value, we're left with a dead write (inside the
      callee) which we can't seem to eliminate without inlining.</p>
    <p>As an example:</p>
    <p>declare i1 @callee(i32* %out) {<br>
        store i32 1, i32* %out<br>
        ret i1 true<br>
      }<br>
      <br>
      declare void @test() {<br>
        %a = alloca i32<br>
         %res = call i1 @callee(i32* %a)<br>
         call void @use(%res)<br>
      }</p>
    <p>If we had similar in spirit to your "nounwindread" but applied to
      the normal return path (e.g. "noreadonreturn"), we could in
      principal leverage this to simplify the callee.  DSE has all the
      information today to annotate "noreadonreturn" arguments at the
      call site.  We could have an IPO transform which merges the
      information from all callees, and drops the writes.  (We could
      also e.g. specialize if not all had the param as dead.)<br>
    </p>
    <p>This particular case isn't strongly motivated enough to bother
      building out infrastructure for, but it's interesting that another
      somewhat analogous use case has popped up.</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>