-
Notifications
You must be signed in to change notification settings - Fork 269
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
Intrinsic test tool to compare neon intrinsics with C #1170
Conversation
r? @Amanieu (rust-highfive has picked a reviewer for you, use r? to override) |
7c99a90
to
feb4217
Compare
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.
I had a lot of trouble getting this to run: it's hard to get an aarch64 clang toolchain set up properly on an x86_64 host. Could you add the intrinsics test to the CI scripts so we can run them in a consistent docker environment?
Overall, this looks great! Do you think this could be extended in the future to support arm and possibly x86 as well? |
CI - I'll take a look at adding it, I'll try to get something done next week for it. arm I think this one should be fairly simple. I suspect it will just be a case of changing the target on the build commands and updating the use statement. The input list would need to be filtered to remove the intrinsics that are AArch64 only though. x86 I haven't looked at those intrinsics in any detail but it looks like the types have different names so it would probably require a few changes to types.rs to emit the right type names (and I suspect the get lane function would have a different name). Also it looks like the type names don't contain as much information as they do on arm so you might just have to treat them as some number of 64 bit values, that shouldn't cause an issue other than the printing of values might not be as human readable. If you could determine the layout while loading the intrinsic list that would be fixed though. Given that it's mostly just creating some values calling a function with those and then printing the return value, I expect it shouldn't be too far away to be honest. |
In stdarch-verify we currently parse the HTML from the ARM website to get a list of all intrinsics and their arguments (crates/stdarch-verify/tests/arm.rs). Is there any difference between this and the data source you are using for your CSV? We have some intrinsics that require that an argument is a compile-time constant, e.g. |
My data source is https://docs.google.com/spreadsheets/d/1MqW1g8c7tlhdRWQixgdWvR4uJHNZzCYAf4V0oHjZkwA/edit#gid=0 it was easier to use that as the first column can be used to check if it's enabled in Rust. As for the compile time constants, in the spreadsheet and documentation they are named |
4311578
to
825329d
Compare
The checker seems to be failing on some intrinsics. Are these real bugs in our implementation? Also some of the C intrinsics fail to run for some reason. |
I haven't had time to investigate the failures properly, but the differences in values could be actual errors with the implementation, when looking at the assembly for some of those the fcvtz(u,s) doesn't appear in the Rust binary. The failure to run the C is because it didn't find the intrinsic, I just remembered I probably need to set the crypto feature. |
Ping @JamieCunliffe! Any progress update on this? From what I can tell the main blockers are:
The implementation itself looks fine otherwise. |
825329d
to
2109b70
Compare
I haven't forgot about this. I just pushed a change that should fix the I plan to take a look at the conversion issue now. |
It looks like the issue with the conversion is due to optimisations, when building the C and Rust with optimisations turned off they produce the same correct output. One set of values that are causing an error are: With optimisations on for converting to u32 Rust produces: If I use As a side note |
This seems to be a case of rust-lang/rust#10184. This was fixed for normal float to int casts but not for However the root cause is that we shouldn't be using This was actually fixed in Clang 12, which produces the correct result: https://godbolt.org/z/jG1x1Yvx5 |
I started a patch to use There is the My thoughts are to use those saturating intrinsics and until LLVM can be updated, add an exception in the instruction count limit to the tests for that intrinsic. Does that seem reasonable? |
Sounds good! |
This tool generates rust and C programs that will call intrinsics and print the results with multiple different inputs. It will build all the programs and then run each of them and diff the output printing any differences that are found. It uses the tracking spreadsheet (with the % column renamed to enabled) to determine which intrinsics to test. It will filter out any intrinsics that have an argument with the name "n" or "lane" as those have constraints on them as to what numbers can be used.
2109b70
to
6056cfc
Compare
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.
It seems good, shall we land it now? :)
Oh! I missed the update since github doesn't give notifications for force-push. Yes, let's merge this! |
As mentioned in #1125 this is the start of a tool to compare the intrinsics between C and Rust.
Some notable things:
lane
orn
argument are skipped due to constraints on the values.I did notice that some of the intrinsics were marked as done in the tracking spreadsheet but didn't actually exist.
I have also noticed that a few vcvt intrinsics have differences, I haven't yet fully investigated that though.