@@ -13,7 +13,8 @@ use rustc_session::{config::OptLevel, DataTypeKind, FieldInfo, SizeKind, Variant
1313use rustc_span:: symbol:: Symbol ;
1414use rustc_span:: { Span , DUMMY_SP } ;
1515use rustc_target:: abi:: call:: {
16- ArgAbi , ArgAttribute , ArgAttributes , ArgExtension , Conv , FnAbi , PassMode , Reg , RegKind ,
16+ ArgAbi , ArgAttribute , ArgAttributes , ArgExtension , Conv , FnAbi , HomogeneousAggregate , PassMode ,
17+ Reg , RegKind ,
1718} ;
1819use rustc_target:: abi:: * ;
1920use rustc_target:: spec:: { abi:: Abi as SpecAbi , HasTargetSpec , PanicStrategy , Target } ;
@@ -3203,10 +3204,27 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
32033204
32043205 if arg. layout . is_unsized ( ) || size > max_by_val_size {
32053206 arg. make_indirect ( ) ;
3207+ } else if let Ok ( HomogeneousAggregate :: Homogeneous ( Reg {
3208+ kind : RegKind :: Float ,
3209+ ..
3210+ } ) ) = arg. layout . homogeneous_aggregate ( self )
3211+ {
3212+ // We don't want to aggregate floats as an aggregates of Integer
3213+ // because this will hurt the generated assembly (#93490)
3214+ //
3215+ // As an optimization we want to pass homogeneous aggregate of floats
3216+ // greater than pointer size as indirect
3217+ if size > Pointer . size ( self ) {
3218+ arg. make_indirect ( ) ;
3219+ }
32063220 } else {
32073221 // We want to pass small aggregates as immediates, but using
32083222 // a LLVM aggregate type for this leads to bad optimizations,
32093223 // so we pick an appropriately sized integer type instead.
3224+ //
3225+ // NOTE: This is sub-optimal because in the case of (f32, f32, u32, u32)
3226+ // we could do ([f32; 2], u64) which is better but this is the best we
3227+ // can do right now.
32103228 arg. cast_to ( Reg { kind : RegKind :: Integer , size } ) ;
32113229 }
32123230 }
@@ -3237,7 +3255,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
32373255 arg. make_indirect ( ) ;
32383256 }
32393257
3240- _ => { } ,
3258+ _ => { }
32413259 }
32423260 } ;
32433261 fixup ( & mut fn_abi. ret ) ;
0 commit comments