-
Notifications
You must be signed in to change notification settings - Fork 280
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
enable assert_instr on wasm32 vector splat operations #569
Conversation
cc @alexcrichton for some reason this passes, I think the simd128 tests are not run on ci :( on my machine this fails
with
which is the error I expect this to produce on CI. |
So I can reproduce, on my machine, the tests fail to build if I execute the command in crates/coresimd, but if I execute it in the root directory by adding |
And indeed |
This is a cargo bug: rust-lang/cargo#5364 |
Ah yeah I tried this awhile back but LLVM didn't have enough support yet unfortunately. We may need to wait a bit longer :( (or maybe update LLVM again?) |
This should already work with LLVM trunk since the LLVM bug for this has been closed with a merged patch. The next time LLVM is updated this should just work. |
Ah unfortunately an LLVM update won't do it at the moment :( Updating LLVM in rust-lang/rust yields:
so a different error! Just still an error :( |
@alexcrichton That bug is good to know about. The fix is very simple, but there are a bunch of similar bugs elsewhere, so I'll try to land patches fixing all of them tomorrow. @gnzlbg FYI, you can see all of the SIMD instructions and intrinsics that have lowering implemented in LLVM tip of tree by looking at https://github.com/llvm-mirror/llvm/blob/master/test/CodeGen/WebAssembly/simd.ll |
Tomorrow is saturday, please enjoy your weekend, this can wait till monday :P |
It was still Thursday in my timezone when I posted that! |
FWIW I was toying around with this last night and was able to get past LLVM (yay!). Not to say I got everything working though! There were a few follow-up problems:
I wasn't able to emit everything and get LLVM to not error, after I enabled the splat operations and got a successful compile I then enabled In any case we can't (and don't really need to?) make much progress here until Node or a browser implements the current version of the SIMD spec. Wanted to at leat provide an update though! @tlively would it be useful to get reduced test cases for LLVM errors? Or is it still too early for that? |
Yes, test cases would be very useful and welcome! The latest one-stop shop to see what instructions are implemented is https://github.com/llvm-mirror/llvm/blob/master/test/MC/WebAssembly/simd-encodings.s. There is also another opcode reorganization in the works here: WebAssembly/simd#42. Once that is settled, LLVM and V8 will finally agree on simd opcodes. |
Ok sure! I've collected some files at https://gist.github.com/alexcrichton/f727348a2d547248b93ec0b8684996af which sould all trigger errors with Now we may also have bad codegen in Rust, if we need to codegen various intrinsics differently just let me know! Also they're all reduced with |
These are great, thank you. One codegen issue I saw was that for any_true and all_true you should use the new @llvm.wasm.anytrue and @llvm.wasm.alltrue intrinsic functions. The @llvm.experimental.vector.reduce.{or,and} intrinsics do not have quite the same semantics as the corresponding WebAssembly instructions. |
Ok cool thanks for the tip! When using those I get, though:
and unfortunately rustc doesn't even get as far as emitting IR so I can't extract a test case :( |
Yikes! That will require some deeper poking around. Would you be able to get an LLVM stack trace for that by any chance? |
Sure yeah, using gdb I get this stack trace |
Another thing I notice is that Rust's use of <1 x i128> is causing the emitted code to store the vector in memory to return it, rather than returning it directly. The best solution will be for me to add support for that type to the LLVM backend. |
Ah that may be because our ABI definition for wasm is super bare bones compare to, for example In any case though we'll want both strategies working in the long run! |
No, this is happening in LLVM. For example, if you look at bug15.ll, you'll see that there are no stores anywhere. But after I fix the codegen issue, LLVM lowers it to take an outparam pointer for the vector and return via a store. |
Ok we're getting really close, thanks so much for all your awesome help here @tlively, the backend is progressing at a lightning pace! Remaining work items I've found are:
And... that may actually be it! I enabled basically all the other operations successfully and hand inspection of the wasm looks like it's all being generated as expected. I can start pushing work to this PR (or a separate PR, either way's fine) once we start getting closer to this all working. |
@alexcrichton I would add one more work item: There is no way to get min/max instructions from the IR yet, but a fix has been accepted and will land very soon. I also want to make sure you're aware of and using all the wasm-specific LLVM intrinsics we have, including:
And I know you're already using Edit: Another work item is that instruction selection crashes when lane indices are `undef, although this may not be affecting Rust's codegen. A fix is out for review. |
Oh heh good point! I wasn't able to test those because our implementation uses I don't think we've bound the saturating arithmetic ones just yet, but I'll be sure to hook into those intrinsics for that and |
Oh also FWIW the |
Ok I'm gonna try to keep making progress on this at #620, so closing in favor of that |
Note: codegen for this is already working in LLVM upstream. This PR currently fails on my machine. It should start passing once we update LLVM upstream.