diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 2cb96c4ec0f5..f9e4a6a352ba 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -302,6 +302,14 @@ fn vector_can_bitcast(x: abi::Scalar) -> bool { let to_backend_ty = bx.cx().immediate_backend_type(cast); OperandValue::Immediate(bx.bitcast(imm, to_backend_ty)) } + ( + OperandValue::Immediate(imm), + abi::BackendRepr::SimdScalableVector { element: from_scalar, .. }, + abi::BackendRepr::SimdScalableVector { element: to_scalar, .. }, + ) if vector_can_bitcast(from_scalar) && vector_can_bitcast(to_scalar) => { + let to_backend_ty = bx.cx().immediate_backend_type(cast); + OperandValue::Immediate(bx.bitcast(imm, to_backend_ty)) + } ( OperandValue::Pair(imm_a, imm_b), abi::BackendRepr::ScalarPair(in_a, in_b), diff --git a/tests/ui/scalable-vectors/transmute.rs b/tests/ui/scalable-vectors/transmute.rs new file mode 100644 index 000000000000..5995aa7dbb2f --- /dev/null +++ b/tests/ui/scalable-vectors/transmute.rs @@ -0,0 +1,39 @@ +//@ build-pass +//@ compile-flags: -Copt-level=3 +//@ only-aarch64 +#![crate_type = "lib"] +#![allow(incomplete_features, internal_features, dead_code, improper_ctypes)] +#![allow(nonstandard_style, private_interfaces)] +#![feature(abi_unadjusted, link_llvm_intrinsics, rustc_attrs)] + +// Tests that use of transmute between `svuint8x2_t` and `svint8x2_t` builds with optimisations +// without any failures from LLVM. + +use std::mem::transmute; + +#[rustc_scalable_vector(16)] +struct svbool_t(bool); + +#[rustc_scalable_vector(16)] +struct svuint8_t(u8); + +#[rustc_scalable_vector] +struct svuint8x2_t(svuint8_t, svuint8_t); + +#[rustc_scalable_vector(16)] +struct svint8_t(i8); + +#[rustc_scalable_vector] +struct svint8x2_t(svint8_t, svint8_t); + +#[target_feature(enable = "sve")] +pub unsafe fn svld2_u8(pg: svbool_t, base: *const i8) -> svuint8x2_t { + unsafe extern "unadjusted" { + #[cfg_attr( + target_arch = "aarch64", + link_name = "llvm.aarch64.sve.ld2.sret.nxv16i8" + )] + fn _svld2_s8(pg: svbool_t, base: *const i8) -> svint8x2_t; + } + transmute(_svld2_s8(pg, base)) +}