Auto merge of #110672 - Ezrashaw:allow-array-simd-in-inline-asm, r=workingjubilee

allow array-style simd in inline asm

Required for [MCP#621](https://github.com/rust-lang/compiler-team/issues/621) to be implemented.

r? `@workingjubilee`
This commit is contained in:
bors 2023-04-24 13:51:04 +00:00
commit b72460fe46
2 changed files with 50 additions and 13 deletions

View File

@ -84,33 +84,45 @@ fn check_asm_operand_type(
ty::Adt(adt, substs) if adt.repr().simd() => {
let fields = &adt.non_enum_variant().fields;
let elem_ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, substs);
match elem_ty.kind() {
ty::Never | ty::Error(_) => return None,
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => {
Some(InlineAsmType::VecI8(fields.len() as u64))
let (size, ty) = match elem_ty.kind() {
ty::Array(ty, len) => {
if let Some(len) =
len.try_eval_target_usize(self.tcx, self.tcx.param_env(adt.did()))
{
(len, *ty)
} else {
return None;
}
}
_ => (fields.len() as u64, elem_ty),
};
match ty.kind() {
ty::Never | ty::Error(_) => return None,
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::VecI8(size)),
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => {
Some(InlineAsmType::VecI16(fields.len() as u64))
Some(InlineAsmType::VecI16(size))
}
ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => {
Some(InlineAsmType::VecI32(fields.len() as u64))
Some(InlineAsmType::VecI32(size))
}
ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => {
Some(InlineAsmType::VecI64(fields.len() as u64))
Some(InlineAsmType::VecI64(size))
}
ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => {
Some(InlineAsmType::VecI128(fields.len() as u64))
Some(InlineAsmType::VecI128(size))
}
ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => {
Some(match self.tcx.sess.target.pointer_width {
16 => InlineAsmType::VecI16(fields.len() as u64),
32 => InlineAsmType::VecI32(fields.len() as u64),
64 => InlineAsmType::VecI64(fields.len() as u64),
16 => InlineAsmType::VecI16(size),
32 => InlineAsmType::VecI32(size),
64 => InlineAsmType::VecI64(size),
_ => unreachable!(),
})
}
ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(fields.len() as u64)),
ty::Float(FloatTy::F64) => Some(InlineAsmType::VecF64(fields.len() as u64)),
ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(size)),
ty::Float(FloatTy::F64) => Some(InlineAsmType::VecF64(size)),
_ => None,
}
}

View File

@ -0,0 +1,25 @@
// assembly-output: emit-asm
// compile-flags: --crate-type=lib
// only-x86_64
// ignore-sgx
#![feature(portable_simd)]
use std::simd::Simd;
use std::arch::asm;
#[target_feature(enable = "avx")]
#[no_mangle]
// CHECK-LABEL: convert:
pub unsafe fn convert(a: *const f32) -> Simd<f32, 8> {
// CHECK: vbroadcastss (%{{[er][a-ds0-9][xpi0-9]?}}), {{%ymm[0-7]}}
let b: Simd<f32, 8>;
unsafe {
asm!(
"vbroadcastss {b}, [{a}]",
a = in(reg) a,
b = out(ymm_reg) b,
);
}
b
}