@@ -358,19 +358,33 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
358358 let field = self . layout . field ( bx. cx ( ) , i) ;
359359 let offset = self . layout . fields . offset ( i) ;
360360
361- let val = if field. is_zst ( ) {
362- OperandValue :: ZeroSized
363- } else if field. size == self . layout . size {
364- assert_eq ! ( offset. bytes( ) , 0 ) ;
365- if let Some ( field_val) = fx. codegen_transmute_operand ( bx, * self , field) {
366- field_val
367- } else {
368- // we have to go through memory for things like
361+ if !bx. is_backend_ref ( self . layout ) && bx. is_backend_ref ( field) {
362+ if let BackendRepr :: Vector { count, .. } = self . layout . backend_repr
363+ && let BackendRepr :: Memory { sized : true } = field. backend_repr
364+ && count. is_power_of_two ( )
365+ {
366+ assert_eq ! ( field. size, self . layout. size) ;
367+ // This is being deprecated, but for now stdarch still needs it for
369368 // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);
370369 let place = PlaceRef :: alloca ( bx, field) ;
371370 self . val . store ( bx, place. val . with_type ( self . layout ) ) ;
372- bx. load_operand ( place) . val
371+ return bx. load_operand ( place) ;
372+ } else {
373+ // Part of https://github.com/rust-lang/compiler-team/issues/838
374+ bug ! ( "Non-ref type {self:?} cannot project to ref field type {field:?}" ) ;
373375 }
376+ }
377+
378+ let val = if field. is_zst ( ) {
379+ OperandValue :: ZeroSized
380+ } else if field. size == self . layout . size {
381+ assert_eq ! ( offset. bytes( ) , 0 ) ;
382+ fx. codegen_transmute_operand ( bx, * self , field) . unwrap_or_else ( || {
383+ bug ! (
384+ "Expected `codegen_transmute_operand` to handle equal-size \
385+ field {i:?} projection from {self:?} to {field:?}"
386+ )
387+ } )
374388 } else {
375389 let ( in_scalar, imm) = match ( self . val , self . layout . backend_repr ) {
376390 // Extract a scalar component from a pair.
@@ -385,11 +399,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
385399 }
386400 }
387401
388- // `#[repr(simd)]` types are also immediate.
389- ( OperandValue :: Immediate ( llval) , BackendRepr :: Vector { .. } ) => {
390- ( None , bx. extract_element ( llval, bx. cx ( ) . const_usize ( i as u64 ) ) )
391- }
392-
393402 _ => {
394403 span_bug ! ( fx. mir. span, "OperandRef::extract_field({:?}): not applicable" , self )
395404 }
@@ -415,14 +424,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
415424 imm
416425 }
417426 }
418- BackendRepr :: Memory { sized : true } => {
419- span_bug ! (
420- fx. mir. span,
421- "Projecting into a simd type with padding doesn't work; \
422- See <https://github.com/rust-lang/rust/issues/137108>",
423- ) ;
424- }
425- BackendRepr :: ScalarPair ( _, _) | BackendRepr :: Memory { sized : false } => bug ! ( ) ,
427+ BackendRepr :: ScalarPair ( _, _) | BackendRepr :: Memory { .. } => bug ! ( ) ,
426428 } )
427429 } ;
428430
0 commit comments