[llvm-bugs] [Bug 41742] New: coroutines: escaping alloca is not included in coroutine frame

via llvm-bugs llvm-bugs at lists.llvm.org
Sat May 4 10:06:21 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=41742

            Bug ID: 41742
           Summary: coroutines: escaping alloca is not included in
                    coroutine frame
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: aykevanlaethem at gmail.com
                CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org

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:
https://gist.github.com/aykevl/7b72e0f5632736149445927a09cd0c2b
I created coro.opt.bc with:
  opt-9 -o coro.opt.bc -coro-early -coro-split -coro-elide coro.ll

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190504/411bb40b/attachment.html>


More information about the llvm-bugs mailing list