<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>