-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Indirect (and direct) tail calls trigger invalid LLVM error #11776
Comments
I am beginning to believe this is a combination of several bugs, some of which are in LLVM itself. Our first issue (easier) is that spilling/saving results after the tail call is causing issues. When generating tail-calls, clang doesn't emit this IR even at -O0. We should probably special-case it (or wait for stage2). This is why direct calls right now are broken. Once we fix that, we can move onto indirect calls (which is also broken in clang....). Zig support for I was able to produce some similar C code that crashed with a similar error: The underlying error from LLVM is the same on both ends. Clang catches it and puts a fancy message on it, Zig just crashes
In both cases, I'm fairly certian the message is from the LLVM verifier. I'm not sure superficially changing the way the verifier checks arguments is safe. The extra "argument" the verifier seems to detect for indirect functions could be there for a good reason (web-assembly something?).
Overall LLVM rules seem unclear here. Looking through the github I see a lot oft compiler nerds debating the exact semantics (surprise) I seem to be running into a lot of bugs here not just in Zig, but also in clang (line between clang/LLVM is blurry). I think we should wait to fix this until clang fixes generating the same IR. NOTE: What I said above about save/restore is really a separate issue from this. |
I have a similar problem to Techcable, but my interpreter may be clearer, and it works (until it doesn't) with -fstage1 (i.e. it uses
If I compile it without the -fstage1, it wants functions without the
which is no more useful. I don't really care which syntax (although the earlier one (without the I have built a whole infrastructure with this, because my initial tests (the top part of the file) worked. So I REALLY hope it can be fixed (and ideally, soon)! My project is kind of dead in the water until I can verify it. I saw this problem before with functions that returned an error union - which should work, but doen't - so I stopped doing that. It looks like there is something that it thinks is being done between the tailcall and the return. Unfortunately -femit-llvm-ir doesn't seem to do anything, so I don't know how else to check. |
@dvmason as you say, there's the same issue with returning error unions. To work around that in the case of returning an error I include an optional pointer to an error and effectively return an error by setting that value. See https://github.com/malcolmstill/foxwren/blob/master/src/interpreter.zig In your case I wonder if it is because the recursive functions are returning The stage2 issue I think is a separate issue, which I am also facing. |
I dumped the IR with --verbose-llvm-ir and discovered that because my tail-called functions were returning i64, the IR that was generated was taking the returned value, and then moving it to %result and then returning that... so LLVM was correct that there was code between the musttail and the return.
Changing my functions to return void, solved the problem. @malcolmstill that sounds like the solution you discovered, too. I am greatly relieved that I found a work-around!!! Now, that is not to say that the problem is fixed... just that I've found a work-around for my case. |
Closes ziglang#4301 Closes ziglang#5692 Closes ziglang#6281 Closes ziglang#10786 Closes ziglang#11149 Closes ziglang#11776
Closes ziglang#4301 Closes ziglang#5692 Closes ziglang#6281 Closes ziglang#10786 Closes ziglang#11149 Closes ziglang#11776
Dear lord, if this works I will be so glad. I was planning to resort to writing my interpreter in C...... |
I was getting desperate too.... I'd been telling everyone how happy I was with Zig.... but was getting worried.... and now I am happy again! |
Closes ziglang#4301 Closes ziglang#5692 Closes ziglang#6281 Closes ziglang#10786 Closes ziglang#11149 Closes ziglang#11776
Zig Version
0.10.0-dev.2461+69323fc14
Steps to Reproduce
To trigger this bug, invoke an (indirect) function pointer with
@call(.{ .modifier = .always_tail })
.Although the frontend runs successfully, the generated LLVM IR is considered invalid.
Here is a minimal test case: https://gist.github.com/9258584d33227d4c85eb81efcfd048a1
Switching to a direct tail call seems to invoke the same bug with invalid LLVM output.
Expected Behavior
Mandatory tail calls should work correctly, both with direct calls and indirect function pointers.
Actual Behavior
Error message (same for direct calls):
Relevant LLVM IR Here is the llvm IR for the direct call ``` %7 = load i64, i64* %val, align 8, !dbg !2629 %8 = musttail call fastcc double @handler_sin(i64 %7), !dbg !2630 store double %8, double* %result, align 8, !dbg !2630 %9 = load double, double* %result, align 8, !dbg !2631 ret double %9, !dbg !2631 ```
Here is the relevant llvm IR for the indirect call:
Motivation & Related issues
The motivating use-case here is a "tail call interpreter" suggested as a workaround to #8220.
A simple example is here.
LLVM gives a different error message for compiling my "simple" interpreter, but I would expect the underlying issues are related.
The text was updated successfully, but these errors were encountered: