@@ -480,8 +480,55 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
480
480
}
481
481
482
482
_ if name. as_str ( ) . starts_with ( "simd_" ) => {
483
+ // Unpack non-power-of-2 #[repr(packed)]
484
+ let mut loaded_args = Vec :: new ( ) ;
485
+ for ( ty, arg) in arg_tys. iter ( ) . zip ( args) {
486
+ loaded_args. push (
487
+ if ty. is_simd ( )
488
+ && let OperandValue :: Ref ( place) = arg. val
489
+ {
490
+ let ( size, elem_ty) = ty. simd_size_and_type ( self . tcx ( ) ) ;
491
+ let elem_ll_ty = match elem_ty. kind ( ) {
492
+ ty:: Float ( f) => self . type_float_from_ty ( * f) ,
493
+ ty:: Int ( i) => self . type_int_from_ty ( * i) ,
494
+ ty:: Uint ( u) => self . type_uint_from_ty ( * u) ,
495
+ ty:: RawPtr ( _, _) => self . type_ptr ( ) ,
496
+ _ => unreachable ! ( ) ,
497
+ } ;
498
+ let loaded =
499
+ self . load_from_place ( self . type_vector ( elem_ll_ty, size) , place) ;
500
+ OperandRef :: from_immediate_or_packed_pair ( self , loaded, arg. layout )
501
+ } else {
502
+ * arg
503
+ } ,
504
+ ) ;
505
+ }
506
+
507
+ let llret_ty = if ret_ty. is_simd ( )
508
+ && let abi:: Abi :: Aggregate { .. } = self . layout_of ( ret_ty) . layout . abi
509
+ {
510
+ let ( size, elem_ty) = ret_ty. simd_size_and_type ( self . tcx ( ) ) ;
511
+ let elem_ll_ty = match elem_ty. kind ( ) {
512
+ ty:: Float ( f) => self . type_float_from_ty ( * f) ,
513
+ ty:: Int ( i) => self . type_int_from_ty ( * i) ,
514
+ ty:: Uint ( u) => self . type_uint_from_ty ( * u) ,
515
+ ty:: RawPtr ( _, _) => self . type_ptr ( ) ,
516
+ _ => unreachable ! ( ) ,
517
+ } ;
518
+ self . type_vector ( elem_ll_ty, size)
519
+ } else {
520
+ llret_ty
521
+ } ;
522
+
483
523
match generic_simd_intrinsic (
484
- self , name, callee_ty, fn_args, args, ret_ty, llret_ty, span,
524
+ self ,
525
+ name,
526
+ callee_ty,
527
+ fn_args,
528
+ & loaded_args,
529
+ ret_ty,
530
+ llret_ty,
531
+ span,
485
532
) {
486
533
Ok ( llval) => llval,
487
534
Err ( ( ) ) => return Ok ( ( ) ) ,
0 commit comments