draft: arch: Add Hexagon HVX instructions#1999
draft: arch: Add Hexagon HVX instructions#1999androm3da wants to merge 2 commits intorust-lang:mainfrom
Conversation
|
r? @folkertdev rustbot has assigned @folkertdev. Use |
|
cc @folkertdev I'm still working out how to get the CI to execute this, I should be able to make it work with |
|
Yeah I figured that would be a bit of a challenge, so more efficient to do that in parallel. |
folkertdev
left a comment
There was a problem hiding this comment.
General note: this looks largely machine-generated? We already have stdarch-gen-loongarch and stdarch-gen-arm, so it's possible to check that in.
Ok, will add the generation script here too. |
crates/core_arch/src/hexagon/hvx.rs
Outdated
| #[inline] | ||
| #[cfg_attr(target_arch = "hexagon", target_feature(enable = "hvxv60"))] | ||
| #[unstable(feature = "stdarch_hexagon", issue = "none")] |
There was a problem hiding this comment.
For most targets we like adding a test that the intrinsic does in fact produce the expected instruction, e.g.
// avx512bw
#[cfg_attr(test, assert_instr(vpabsw))]
// wasm
#[cfg_attr(test, assert_instr(v128.load8x8_s))]
especially if you are machine-generating these that should hopefully be straightforward.
crates/core_arch/src/hexagon/hvx.rs
Outdated
| /// Execution Slots: SLOT0123 | ||
| #[inline] | ||
| #[cfg_attr(target_arch = "hexagon", target_feature(enable = "hvxv60"))] | ||
| #[unstable(feature = "stdarch_hexagon", issue = "none")] |
There was a problem hiding this comment.
before we merge this you can create a tracking issue in the main repo, see e.g. rust-lang/rust#117427
crates/core_arch/src/hexagon/hvx.rs
Outdated
| #[cfg_attr(target_arch = "hexagon", target_feature(enable = "hvxv60"))] | ||
| #[unstable(feature = "stdarch_hexagon", issue = "none")] | ||
| pub unsafe fn q6_v_vxor_vv(vu: HvxVector, vv: HvxVector) -> HvxVector { | ||
| vxor(vu, vv) |
There was a problem hiding this comment.
it's a bit hard to deduce from the names, but I'm assuming this corresponds to simd_xor
https://doc.rust-lang.org/nightly/std/intrinsics/simd/fn.simd_xor.html
We generally prefer using functions from crate::intrinsics::simd (starting with crate is deliberate, using core:: can cause trouble when bootstrapping). It's much easier for us to then know what a function does, and as a bonus Miri will be able to run the intrinsics too.
When using intrinsics::simd it is even more important to check that these functions emit the right instruction. Sometimes additional optimizations are needed in LLVM to make that work.
I think it's fine to do this gradually, but for some of the simpler operations it's probably possible to do it from the start.
There was a problem hiding this comment.
for some of the simpler operations it's probably possible to do it from the start.
Sure - can do!
Ah - okay, I see that these are different from what I've implemented. I have a python script that takes a C/C++ toolchain header file as a source-of-truth. So @folkertdev should I implement that instead as a crate that parses a yaml file? |
|
The input is up to you, We would prefer having rust over python though, hopefully that is straightforward to port? |
It is, yeah.
Sorry, not sure if I follow. Add comments in the C header file used as an input? Or ... ? |
|
Taking Maybe this was unclear, but currently the workflow is that we don't manually update the generated rust code, but instead modify the inputs to the generator and re-run it. That is convenient when new instructions are added, and it is usually simpler to edit the input than the output. Anyhow, none of that is official, that's just what we have. So if there are good reasons to deviate from it that is something we can discuss. |
Ah okay I gotcha now. So my plan was to just include a hardcoded list in the script/rust program of the intrinsics that do map to the architecture-independent ones and the exceptions get lowered to the architecture-specific ones. |
|
Cool, that should work |
|
doing a quick close/open here to see what CI says now that the features are available |
|
hmm is there some issue with hexagon in |
This I have been noodling over the design of this PR and have several local changes. None of them were intended to address the |
|
Weird. We're using latest nightly here, maybe something was not synchronized? |
Yeah, it's not obvious to me yet. This was fixed a while ago (rust-lang/compiler-builtins#682). I'll need to spend some time trying to reproduce it and maybe something just needs to update an explicit compiler-builtins dependency to a newer release. |
|
Oh, yes, it's building |
|
Note that we don't use crates.io c-b anymore, it should only ever be coming via the submodule which is actively updated. Think this will still technically show as 0.1.160 though. |
folkertdev
left a comment
There was a problem hiding this comment.
Any luck with figuring out why the build fails?
crates/core_arch/src/hexagon/hvx.rs
Outdated
| //! This implementation targets 128-byte mode by default. To change the vector | ||
| //! length mode, use the appropriate target feature when compiling: | ||
| //! - For 128-byte mode: `-C target-feature=+hvx-length128b` | ||
| //! - For 64-byte mode: `-C target-feature=+hvx-length64b` |
There was a problem hiding this comment.
This doesn't work unless you also pass -Zbuild-std. Normally when you compile a program, you're using a pre-built std that uses the default configuration.
There was a problem hiding this comment.
On other targets, the types and intrinsics are actually available unconditionally. It is just UB to call the intrinsics that need a target feature when that feature is not present.
e.g. on x86_64 the namespacing is in the name _mm vs _mm256 etc. Here maybe we should namespace with a module, so have a 64 and 128-byte module, both of which are available unconditionally, but of course need the target feature to actually use the intrinsics.
but maybe there are additional details that I'm missing?
There was a problem hiding this comment.
Any luck with figuring out why the build fails?
Sorry, I haven't spent enough time looking into this in the last few days. I'll dig in and sort it out.
This doesn't work unless you also pass
-Zbuild-std. Normally when you compile a program, you're using a pre-builtstdthat uses the default configuration.
Not for hexagon, though. Since its artifacts aren't included, -Zbuild-std is a fairly convenient way to resolve that dependency.
maybe there are additional details that I'm missing?
Yeah - it's kinda inconvenient that the ISA was designed this way. But it was. The semantics of the instructions change based on the system mode. Either the system is in 64-byte mode, or it's in 128-byte mode. The register size depends on the mode. In practice, modern parts only support 128-byte mode. But several DSPs were made with only 64-byte mode, and several with support for both modes. So we're stuck with the LLVM backend looking and behaving the way it does in order to target all the various Hexagon HVX coprocs out there. You'll see C/C++ code handle these intrinsics and their types by considering the __HVX_LENGTH__ preprocessor definition that's emitted. If there's a better way to handle it for rust than how it's being done here, I'm happy to consider another approach.
I'll start by documenting the above details in the crate's user documentation so that it's less confusing for all involved.
There was a problem hiding this comment.
Hmm but now re-reading what you've said I think I misunderstood your suggestion.
Here maybe we should namespace with a module, so have a 64 and 128-byte module, both of which are available unconditionally, but of course need the target feature to actually use the intrinsics.
Yeah sorry for the confusion -- this should be do-able.
There was a problem hiding this comment.
Rebased and squashed the commits for this PR, leaving the 64b/128b crate split as its own commit to make it easier to see what changed from the previous commit set.
Any luck with figuring out why the build fails?
Tsk! rust-lang/compiler-builtins#1066 -- dunno why I thought the symbol would be private but that was the issue.
Note: this depends on #151500
Tracking issue #151523