Compiling the following inline assembly:
#![feature(portable_simd)]
use std::simd::{i64x8, f64x8};
use std::arch::asm;
pub fn convert(a: i64x8) -> f64x8{
let converted: f64x8;
unsafe {
asm!(
"vcvtqq2pd {converted} {a}",
a = in(zmm_reg) a,
converted = out(zmm_reg) converted,
);
}
converted
}
Leads to the errors:
error: cannot use value of type `Simd<i64, 8>` for inline assembly
--> <source>:12:25
|
12 | a = in(zmm_reg) a,
| ^
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
error: cannot use value of type `Simd<f64, 8>` for inline assembly
--> <source>:13:34
|
13 | converted = out(zmm_reg) converted,
| ^^^^^^^^^
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
error: aborting due to 2 previous errors
You will need -C target-feature= avx512f
to compile the above. Alternatively see this godbolt
This doesn't make a ton of sense to me because the inline assembly docs clearly state that f64x8
and i64x8
are acceptable input types for zmm_reg
.
Additionally the error message states that SIMD vectors are acceptable, but thats what I'm inputting.
If its relevant this reproduces on:
active toolchain
----------------
nightly-x86_64-unknown-linux-gnu (default)
rustc 1.68.0-nightly (afaf3e07a 2023-01-14)
Is this a rust bug or am I doing something wrong?
CodePudding user response:
As mentioned in the comments, the compiler doesn't yet support using portable simd types in assembly (relevant issue). Note that not all portable simd types can be sent to assembly, things like using an f64x16
type is perfectly legal, but I do not know of any supported architecture that could handle the equivalent type. As a workaround, use the platform specific vector types, such as __m512i
or __m512d
.
#![feature(portable_simd)]
#![feature(stdsimd)]
use std::simd::{i64x8, f64x8};
use std::arch::asm;
use std::arch::x86_64::*;
pub fn convert(a: i64x8) -> f64x8{
let a = __mm512i::from(a);
let converted: __mm512d;
unsafe {
asm!(
"vcvtqq2pd {converted}, {a}",
a = in(zmm_reg) a,
converted = out(zmm_reg) converted,
);
}
converted.into()
}
Of course, if you're doing that, try to write your code with the appropriate simd intrinsics instead of assembly if possible, to help enable the compiler to optimize your code.