-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Ensure NoTrapAfterNoreturn is false for the wasm backend #65876
Conversation
Add the command line flag --no-trap-after-noreturn. Add and improve tests related to WebAssembly's unreachable instruction. Also fix various typos.
As an aside, here's a thought that occurred to me while reading through the code: It would be nice if LLVM IR's |
The new peephole optimisation removed an unreachable in this test.
@llvm/pr-subscribers-lld-wasm ChangesIn the WebAssembly back end, the TrapUnreachable option is currently load-bearing for correctness, inserting wasm The first commit adds a command line flag for NoTrapAfterNoreturn so that it can be tested, and adds new tests (and fixes some typos).
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't read the code yet, but I wonder, why can't we turn NoTrapAfterNoreturn
on? Do we need unreachable
after noreturn
calls?
Also please run |
We do for most cases, because the body of a wasm function has to pass wasm validation. This means that the body has to have the same "type" as the function signature, even if the end of the function is never reached. Wasm This is something that native-style architectures don't require, which is kinda what I was getting at with my earlier comment about an UB instruction, to better support these kinds of virtual ISAs. |
Hmm, I'm not sure how I could create another pull request that is stacked on top of this one for the peephole optimisation. Searching around in the LLVM discord, it seems like that's a bit of a pain point at the moment. |
I don't think the stacked PR feature exists in Github, which was a nice feature in Phabricator. You can either upload the next PR now that includes both PR's changes and rebase after this lands, or you can wait until this lands first and then create a new PR. Oh, I have seen my colleague using this plugin (https://app.graphite.dev/) for stacked PRs, but I haven't used it myself and don't know how to use it. |
Here's the new pull request for the peephole optimisation: #66062 |
Are there any more thoughts, opinions, or questions about this PR? |
This looks generally fine to me, but I think for the new |
Do you mean that there should be a test that checks that the Would that be a unit test, or an llvm-lit style test? Where might that test live? After a quick search the closest thing I could find for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the long delay; I was OOO for a while.
Sorry again; I'm still having a hard time understanding what this PR is trying to achieve. See inline comments.
@aheejin I suggest looking at each of the first three commits individually. I carefully crafted and stacked them so that the test passes after each commit. That way, the changes to the test declaratively describe the effect of each commit. I probably should have mentioned that earlier. It seems like GitHub doesn't surface this stacked-commit style information as well as it could. I was following nikic's guide for the old pull request system, where I assume this style was better supported. I'll give a quick overview of what each of the first three commits do:
* Incidently, is this already buggy? We are overwriting our user's TargetOptions, and so if they re-used that object for a different backend they might be surprised by it changing on them. Should we be copying the whole TargetOptions instead? |
I don't think they are the same thing. As I said above,
But The reason I said this might count as an improvement was, in a hypothetical scenario when the default value for
This is a case where the Also I'm having a hard time understanding your criteria between wishy-washy request and real contradiction still. To my understanding in both cases they are not compatible.
Yeah I get that we haven't been warning about a similar case ( For example, that |
I think perhaps the misunderstanding here is that So adding this option allows us to test something that wasn't testable via the command line, but was exposed via the API? Is that right? |
Ah, so it was already possible to set |
Yeah you've got it, that's the main point. It can be set via the C++ API, and when I tried doing so in the Rust compiler I found it broke the WebAssembly backend. Sorry if I didn't make that clear enough earlier, I'm glad we're on the same page now. |
The other points I tried to say in #65876 (comment) stay the same though. |
You might be right, but my feeling is that the behaviour of This change is consistent with the current behaviour and fixes a real issue, so I think it makes sense for this change to go in first, before we start to think about changing any existing behaviour. |
OK fair enough. Sorry that this PR is taking so long time. I guess we can land this after we fix some tests / add some comments. I still think the test file needs more comments; I would like that the readers of the test file find it easy enough to figure out what the purpose of the tests in that file is, without referring to |
That's a good point, I'll add some more explanatory comments. |
call void @ext_never_return() | ||
ret void | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No newline at the end
Co-authored-by: Heejin Ahn <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your patience! Will merge this.
In the WebAssembly back end, the TrapUnreachable option is currently load-bearing for correctness, inserting wasm `unreachable` instructions where needed to create valid wasm. There is another option, NoTrapAfterNoreturn, that removes some of those traps and causes incorrect wasm to be emitted. This turns off `NoTrapAfterNoreturn` for the Wasm backend and adds new tests.
Some textual editing errors got through this pull request that was merged a few weeks ago: #65876 This patch clears up the unintentional duplicated line, and white-space at the end of the lines.
In the WebAssembly back end, the TrapUnreachable option is currently load-bearing for correctness, inserting wasm
unreachable
instructions where needed to create valid wasm. There is another option, NoTrapAfterNoreturn, that removes some of those traps and causes incorrect wasm to be emitted.The first commit adds a command line flag for NoTrapAfterNoreturn so that it can be tested, and adds new tests (and fixes some typos).
The second commit turns off NoTrapAfterNoreturn for the Wasm backend.
The third commit adds a new peephole optimisation, to remove some common cases of unnecessary instructions around
unreachable
. Properly modelling howunreachable
can be a sink and a source for operands would be better, but this will do for now.