<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - coroutines: escaping alloca is not included in coroutine frame"
   href="https://bugs.llvm.org/show_bug.cgi?id=41742">41742</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>coroutines: escaping alloca is not included in coroutine frame
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>aykevanlaethem@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The alloca (n.alloca) in the following function is not included in the
coroutine frame, while I think it should.


define i8* @f(i32 %n) {
entry:
  %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
  %size = call i32 @llvm.coro.size.i32()
  %alloc = call i8* @malloc(i32 %size)
  %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %alloc)
  %n.alloca = alloca i32
  store i32 %n, i32* %n.alloca
  store i32* %n.alloca, i32** @G
  br label %loop
loop:
  %n.val = call i32 @next()
  call void @print(i32 %n.val)
  %0 = call i8 @llvm.coro.suspend(token none, i1 false)
  switch i8 %0, label %suspend [i8 0, label %loop
                                i8 1, label %cleanup]
cleanup:
  %mem = call i8* @llvm.coro.free(token %id, i8* %hdl)
  call void @free(i8* %mem)
  br label %suspend
suspend:
  %unused = call i1 @llvm.coro.end(i8* %hdl, i1 false)
  ret i8* %hdl
}


This is the IR that shows the alloca that is not included in the frame:


define i8* @f(i32 %n) {
entry:
  %id = call token @llvm.coro.id(i32 0, i8* null, i8* bitcast (i8* (i32)* @f to
i8*), i8* bitcast ([3 x void (%f.Frame*)*]* @f.resumers to i8*))
  %alloc = call i8* @malloc(i32 24)
  %hdl = call noalias nonnull i8* @llvm.coro.begin(token %id, i8* %alloc)
  %FramePtr = bitcast i8* %hdl to %f.Frame*
  %resume.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32 0,
i32 0
  store void (%f.Frame*)* @f.resume, void (%f.Frame*)** %resume.addr
  %destroy.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32 0,
i32 1
  store void (%f.Frame*)* @f.destroy, void (%f.Frame*)** %destroy.addr
  %n.alloca = alloca i32
  store i32 %n, i32* %n.alloca
  store i32* %n.alloca, i32** @G
  call void @coro.devirt.trigger(i8* null)
  %n.val = call i32 @next()
  call void @print(i32 %n.val)
  %index.addr1 = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32 0,
i32 3
  store i1 false, i1* %index.addr1
  ret i8* %hdl
}


My understanding is that all local variables that may be live across a suspend
point, should be included in the coroutine frame. In this case, %n.alloca
escapes from the function so it should be considered live in all basic blocks
that dominate the alloca.

Full source code:
<a href="https://gist.github.com/aykevl/7b72e0f5632736149445927a09cd0c2b">https://gist.github.com/aykevl/7b72e0f5632736149445927a09cd0c2b</a>
I created coro.opt.bc with:
  opt-9 -o coro.opt.bc -coro-early -coro-split -coro-elide coro.ll</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>