Ban projecting into SIMD types [MCP838]
This commit is contained in:
@@ -329,20 +329,11 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
|
|||||||
let offset = self.layout.fields.offset(i);
|
let offset = self.layout.fields.offset(i);
|
||||||
|
|
||||||
if !bx.is_backend_ref(self.layout) && bx.is_backend_ref(field) {
|
if !bx.is_backend_ref(self.layout) && bx.is_backend_ref(field) {
|
||||||
if let BackendRepr::SimdVector { count, .. } = self.layout.backend_repr
|
|
||||||
&& let BackendRepr::Memory { sized: true } = field.backend_repr
|
|
||||||
&& count.is_power_of_two()
|
|
||||||
{
|
|
||||||
assert_eq!(field.size, self.layout.size);
|
|
||||||
// This is being deprecated, but for now stdarch still needs it for
|
|
||||||
// Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);
|
|
||||||
let place = PlaceRef::alloca(bx, field);
|
|
||||||
self.val.store(bx, place.val.with_type(self.layout));
|
|
||||||
return bx.load_operand(place);
|
|
||||||
} else {
|
|
||||||
// Part of https://github.com/rust-lang/compiler-team/issues/838
|
// Part of https://github.com/rust-lang/compiler-team/issues/838
|
||||||
bug!("Non-ref type {self:?} cannot project to ref field type {field:?}");
|
span_bug!(
|
||||||
}
|
fx.mir.span,
|
||||||
|
"Non-ref type {self:?} cannot project to ref field type {field:?}",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let val = if field.is_zst() {
|
let val = if field.is_zst() {
|
||||||
|
|||||||
@@ -721,6 +721,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if adt_def.repr().simd() {
|
||||||
|
self.fail(
|
||||||
|
location,
|
||||||
|
format!(
|
||||||
|
"Projecting into SIMD type {adt_def:?} is banned by MCP#838"
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
|
let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
|
||||||
let Some(field) = adt_def.variant(var).fields.get(f) else {
|
let Some(field) = adt_def.variant(var).fields.get(f) else {
|
||||||
fail_out_of_bounds(self, location);
|
fail_out_of_bounds(self, location);
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
//@compile-flags: -Copt-level=3
|
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
|
||||||
#![feature(repr_simd, core_intrinsics)]
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
#[repr(simd)]
|
|
||||||
struct i32x4([i32; 4]);
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn to_array4(a: i32x4) -> [i32; 4] {
|
|
||||||
a.0
|
|
||||||
}
|
|
||||||
|
|
||||||
// CHECK-LABEL: simd_add_self_then_return_array(
|
|
||||||
// CHECK-SAME: ptr{{.+}}sret{{.+}}%[[RET:.+]],
|
|
||||||
// CHECK-SAME: ptr{{.+}}%a)
|
|
||||||
#[no_mangle]
|
|
||||||
pub fn simd_add_self_then_return_array(a: &i32x4) -> [i32; 4] {
|
|
||||||
// It would be nice to just ban `.0` into simd types,
|
|
||||||
// but until we do this has to keep working.
|
|
||||||
// See also <https://github.com/rust-lang/rust/issues/105439>
|
|
||||||
|
|
||||||
// CHECK: %[[T1:.+]] = load <4 x i32>, ptr %a
|
|
||||||
// CHECK: %[[T2:.+]] = shl <4 x i32> %[[T1]], {{splat \(i32 1\)|<i32 1, i32 1, i32 1, i32 1>}}
|
|
||||||
// CHECK: store <4 x i32> %[[T2]], ptr %[[RET]]
|
|
||||||
let a = *a;
|
|
||||||
let b = unsafe { core::intrinsics::simd::simd_add(a, a) };
|
|
||||||
to_array4(b)
|
|
||||||
}
|
|
||||||
18
tests/ui/mir/validate/project-into-simd.rs
Normal file
18
tests/ui/mir/validate/project-into-simd.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// Optimized MIR shouldn't have critical call edges
|
||||||
|
//
|
||||||
|
//@ build-fail
|
||||||
|
//@ edition: 2021
|
||||||
|
//@ compile-flags: --crate-type=lib
|
||||||
|
//@ failure-status: 101
|
||||||
|
//@ dont-check-compiler-stderr
|
||||||
|
|
||||||
|
#![feature(repr_simd)]
|
||||||
|
|
||||||
|
#[repr(simd)]
|
||||||
|
pub struct U32x4([u32; 4]);
|
||||||
|
|
||||||
|
pub fn f(a: U32x4) -> [u32; 4] {
|
||||||
|
a.0
|
||||||
|
//~^ ERROR broken MIR in Item
|
||||||
|
//~| ERROR Projecting into SIMD type U32x4 is banned by MCP#838
|
||||||
|
}
|
||||||
@@ -10,7 +10,9 @@ struct i32x4([i32; 4]);
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_array(a: i32x4) -> [i32; 4] {
|
fn to_array(a: i32x4) -> [i32; 4] {
|
||||||
a.0
|
// This was originally just `a.0`, but that ended up being annoying enough
|
||||||
|
// that it was banned by <https://github.com/rust-lang/compiler-team/issues/838>
|
||||||
|
unsafe { std::mem::transmute(a) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
Reference in New Issue
Block a user