-
Notifications
You must be signed in to change notification settings - Fork 46
Fix loops in clang >= 12 #121
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
Conversation
Some now-legacy Apple toolchains used these versions of Clang.
|
Thank you for your contribution! A couple questions:
So far the generated code has been target independent and target specific differences have been implemented through the pre-processor instead of compiler flags. For example, see #101. Could the fix maybe be implemented via a define? |
If an infinite loop occurs in WASM code recompiled with thoe Clang/LLVM versions, it would be UB, even though the C standard and other compilers define that behavior.
This volatile
Probably; I'll see (edit: I just switched to a macro) |
This reverts commit a3c0c33.
So the fix is not for labels, but actually (infinite) loops? I'm a bit confused why the code is needed at the start of a label. Do you have an example of a WebAssembly module for which the current code gets miscompiled by clang <= 12?
Do you have a link to that issue? What does the |
That's a good point; the code is at the start of a label to begin all basic blocks, but you're right about only needing it in loops. You can try
The |
|
Note: iirc the |
|
Thank you for the explanation and the link! |
|
So I tried to verify both the bug, and the fix, given the example you provided, and I'm still a bit confused: (module (func (export "ub") (result i32) (loop $loop (br $loop)) i32.const 1))gets translated to typedef unsigned int U32;
U32 f0(void) {
U32 si0;
L1:;
{
goto L1;
}
si0=1U;
L0:;
return si0;
}Testing compilation of this function with f0():
.LBB0_1:
jmp .LBB0_1However, versions >=12 start to optimize away the loop, including latest clang 20: https://godbolt.org/z/eMGqqv3r4 (try selecting other version) f0():So should When trying to include the fix, clang shows an error: It looks like the function is missing an argument and should be |
Well that seems like a bug (C permits
Updating rn |
|
Yeah, this might just be llvm/llvm-project#60622, which looks like a "wontfix". Let's just ensure the generated C code will have the behaviour of the original WebAssembly module, a proper infinite loop, and ensure the loop is not optimized away. From what it looks like that starts in clang 12 |
|
Once the version range is adjusted I'm happy to merge this. Thank you for bringing this up and submitting a fix 🙏 |
Co-authored-by: Bastian Müller <[email protected]>
It turns out the godbolt links were c++, which has different forward progress rules. We might need to revert this PR. wdyt? |
|
Ugh, wow, I had no idea that would make a difference. I tried several older and newer clang versions on multiple architectures on Compiler Explorer (with However, if the issue is then that the generated C code changes semantics when compiled as C++, maybe the workaround shouldn't be removed, but rather be applied if the code is compiled a C++. Maybe the ifdef should just be |
|
Good point. I'll submit a follow-up after I get a stable connection to my computer. |
|
Just opened #122 |
Some now-legacy Apple toolchains used these versions of Clang.