@@ -3194,7 +3194,22 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
31943194 }
31953195
31963196 match arg. layout . abi {
3197- Abi :: Aggregate { .. } => { }
3197+ Abi :: Aggregate { .. } => {
3198+ // Pass and return structures up to 2 pointers in size by value,
3199+ // matching `ScalarPair`. LLVM will usually pass these in 2 registers
3200+ // which is more efficient than by-ref.
3201+ let max_by_val_size = Pointer . size ( self ) * 2 ;
3202+ let size = arg. layout . size ;
3203+
3204+ if arg. layout . is_unsized ( ) || size > max_by_val_size {
3205+ arg. make_indirect ( ) ;
3206+ } else {
3207+ // We want to pass small aggregates as immediates, but using
3208+ // a LLVM aggregate type for this leads to bad optimizations,
3209+ // so we pick an appropriately sized integer type instead.
3210+ arg. cast_to ( Reg { kind : RegKind :: Integer , size } ) ;
3211+ }
3212+ }
31983213
31993214 // This is a fun case! The gist of what this is doing is
32003215 // that we want callers and callees to always agree on the
@@ -3220,24 +3235,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
32203235 && self . tcx . sess . target . simd_types_indirect =>
32213236 {
32223237 arg. make_indirect ( ) ;
3223- return ;
32243238 }
32253239
3226- _ => return ,
3227- }
3228-
3229- // Pass and return structures up to 2 pointers in size by value, matching `ScalarPair`.
3230- // LLVM will usually pass these in 2 registers, which is more efficient than by-ref.
3231- let max_by_val_size = Pointer . size ( self ) * 2 ;
3232- let size = arg. layout . size ;
3233-
3234- if arg. layout . is_unsized ( ) || size > max_by_val_size {
3235- arg. make_indirect ( ) ;
3236- } else {
3237- // We want to pass small aggregates as immediates, but using
3238- // a LLVM aggregate type for this leads to bad optimizations,
3239- // so we pick an appropriately sized integer type instead.
3240- arg. cast_to ( Reg { kind : RegKind :: Integer , size } ) ;
3240+ _ => { } ,
32413241 }
32423242 } ;
32433243 fixup ( & mut fn_abi. ret ) ;
0 commit comments