Skip to content

Commit

Permalink
Rollup merge of rust-lang#110672 - Ezrashaw:allow-array-simd-in-inlin…
Browse files Browse the repository at this point in the history
…e-asm, r=workingjubilee

allow array-style simd in inline asm

Required for [MCP#621](rust-lang/compiler-team#621) to be implemented.

r? `@workingjubilee`
  • Loading branch information
matthiaskrgr authored Apr 22, 2023
2 parents 15648f8 + 8534183 commit f4c51bf
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 13 deletions.
38 changes: 25 additions & 13 deletions compiler/rustc_hir_analysis/src/check/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,33 +84,45 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
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,
}
}
Expand Down
25 changes: 25 additions & 0 deletions tests/assembly/asm/inline-asm-avx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// assembly-output: emit-asm
// compile-flags: --crate-type=lib
// compile-flags: --target x86_64-unknown-linux-gnu
// needs-llvm-components: x86

#![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
}

0 comments on commit f4c51bf

Please sign in to comment.