about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2025-03-06 19:13:46 -0800
committerScott McMurray <scottmcm@users.noreply.github.com>2025-07-20 10:22:09 -0700
commit41ce1ed252f194756fb2f3e3e92bbdfb3940088d (patch)
tree6d723fea3a43e0424cb4575ce2c2b80bd5a77120
parentf790042c6ab3cf05622e63928b13cb802d68fadf (diff)
downloadrust-41ce1ed252f194756fb2f3e3e92bbdfb3940088d.tar.gz
rust-41ce1ed252f194756fb2f3e3e92bbdfb3940088d.zip
Ban projecting into SIMD types [MCP838]
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs19
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs9
-rw-r--r--tests/codegen/simd/project-to-simd-array-field.rs31
-rw-r--r--tests/ui/mir/validate/project-into-simd.rs18
-rw-r--r--tests/ui/simd/issue-105439.rs4
5 files changed, 35 insertions, 46 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 6a3fdb6ede1..06bedaaa4a2 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -329,20 +329,11 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
         let offset = self.layout.fields.offset(i);
 
         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
-                bug!("Non-ref type {self:?} cannot project to ref field type {field:?}");
-            }
+            // Part of https://github.com/rust-lang/compiler-team/issues/838
+            span_bug!(
+                fx.mir.span,
+                "Non-ref type {self:?} cannot project to ref field type {field:?}",
+            );
         }
 
         let val = if field.is_zst() {
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 659ca4df159..5860072d541 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -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 Some(field) = adt_def.variant(var).fields.get(f) else {
                             fail_out_of_bounds(self, location);
diff --git a/tests/codegen/simd/project-to-simd-array-field.rs b/tests/codegen/simd/project-to-simd-array-field.rs
deleted file mode 100644
index 29fab640633..00000000000
--- a/tests/codegen/simd/project-to-simd-array-field.rs
+++ /dev/null
@@ -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)
-}
diff --git a/tests/ui/mir/validate/project-into-simd.rs b/tests/ui/mir/validate/project-into-simd.rs
new file mode 100644
index 00000000000..67766c8c4b0
--- /dev/null
+++ b/tests/ui/mir/validate/project-into-simd.rs
@@ -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
+}
diff --git a/tests/ui/simd/issue-105439.rs b/tests/ui/simd/issue-105439.rs
index 0a44f36fb2e..1d57eff341c 100644
--- a/tests/ui/simd/issue-105439.rs
+++ b/tests/ui/simd/issue-105439.rs
@@ -10,7 +10,9 @@ struct i32x4([i32; 4]);
 
 #[inline(always)]
 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() {