]> git.lizzy.rs Git - rust.git/blobdiff - src/value_and_place.rs
Make it possible it use value_field for SIMD values stored ByVal
[rust.git] / src / value_and_place.rs
index 5ae1e9b06afba1f2fd6073088a0e22a90a753149..cb23c814b5d2d6bd038c6821a85da12de075e2eb 100644 (file)
@@ -167,13 +167,26 @@ pub fn value_field<'a>(
         field: mir::Field,
     ) -> CValue<'tcx> {
         let layout = self.1;
-        let ptr = match self.0 {
-            CValueInner::ByRef(ptr) => ptr,
+        match self.0 {
+            CValueInner::ByVal(val) => {
+                match layout.abi {
+                    layout::Abi::Vector { element: _, count } => {
+                        let count = u8::try_from(count).expect("SIMD type with more than 255 lanes???");
+                        let field = u8::try_from(field.index()).unwrap();
+                        assert!(field < count);
+                        let lane = fx.bcx.ins().extractlane(val, field);
+                        let field_layout = layout.field(&*fx, usize::from(field));
+                        CValue::by_val(lane, field_layout)
+                    }
+                    _ => unreachable!("value_field for ByVal with abi {:?}", layout.abi),
+                }
+            }
+            CValueInner::ByRef(ptr) => {
+                let (field_ptr, field_layout) = codegen_field(fx, ptr, None, layout, field);
+                CValue::by_ref(field_ptr, field_layout)
+            }
             _ => bug!("place_field for {:?}", self),
-        };
-
-        let (field_ptr, field_layout) = codegen_field(fx, ptr, None, layout, field);
-        CValue::by_ref(field_ptr, field_layout)
+        }
     }
 
     pub fn unsize_value<'a>(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, dest: CPlace<'tcx>) {