New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C++20 coroutine miscompiled if it contains a dispatch table + computed goto #56436
Comments
Looking at the output of
I think the underlying root cause here is that the labels stored in the The problem becomes even more apparent in https://godbolt.org/z/7aYaG9xfE, where the Judging by the assembly generated by gcc (https://godbolt.org/z/PMsqY5e5Y), it seems that they are able to avoid this problem, by splitting the coroutine in a different way: While LLVM duplicates the complete interpreter loop and its labels in both the ramp and the resume function. gcc instead only emits the interpreter loop in the "actor" function (== LLVM's resume function), and calls the actor function from the ramp function. @ChuanqiXu9 FYI |
Thanks for reporting. I'll take a look. |
@llvm/issue-subscribers-c-20 |
@llvm/issue-subscribers-coroutines |
Your analysis is basically correct. And this one is not easy to fix. The biggest difference of coroutines between clang and gcc is that gcc handles coroutines in the frontend but clang handles it in the middle end. This brings many differences. For example, in the frontend, we could scope informations. But in the middle end, we will store them in a global variable and there is no information about scopes. And it doesn't make a lot of sense to copy a global variable when splitting coroutines. Also the computed goto are not standard C++. It is a GCC extension although clang supports it too. So I prefer to add a warning/error instead of doing some hacks for the non-stantandard use cases. |
And from the link you pasted, |
I agree. A warning should be fine for the time being. In case there is larger demand for combining computed goto with coroutines, we can still add support for that later. It took a pretty long time to understand why the interpreter didn't work as expected. (I was trying this on a much bigger, real-world production interpreter for SQL queries originally...) A clear warning/error would have saved me a lot of time. I think, we should furthermore disable inlining of any function which contains computed-gotos into a coroutine function.
right
yes, that works, but it does not give me the performance I needed. For https://godbolt.org/z/17G8jGbse, it is vital that LLVM does not inline the |
Currently, the LLVM will not inline these kind of function by default: https://godbolt.org/z/v4Kvqrfzj. So we could only emit an error for it simply. I'll try to make it.
Just out of interesting, how much is the performance gap? |
Closing #56436 We can't support the GNU address of label extension in coroutines well in current architecture. Since the coroutines are going to split into pieces in the middle end so the address of labels are ambiguous that time. To avoid any further misunderstanding, we try to emit an error here. Differential Revision: https://reviews.llvm.org/D131938
Closing llvm/llvm-project#56436 We can't support the GNU address of label extension in coroutines well in current architecture. Since the coroutines are going to split into pieces in the middle end so the address of labels are ambiguous that time. To avoid any further misunderstanding, we try to emit an error here. Differential Revision: https://reviews.llvm.org/D131938
Closing, as this was fixed in cc526e3 which will ship with clang-16 |
Repro: https://godbolt.org/z/j3o96sYd1
clang trunk accepts the program, but miscompiles it.
gcc trunk compiles the program correctly.
The program implements a simple interpreter using the a dispatch table as described, e.g., in https://eli.thegreenplace.net/2012/07/12/computed-goto-for-efficient-dispatch-tables.
The problem only occurs when combining coroutines with a dispatch table and a computed goto. A switch-based interpreter works as expected.
The text was updated successfully, but these errors were encountered: