@@ -727,6 +727,7 @@ fn fn_abi_adjust_for_abi<'tcx>(
727
727
728
728
match arg. layout . abi {
729
729
Abi :: Aggregate { .. } => { }
730
+ Abi :: ScalarPair ( ..) => { }
730
731
731
732
// This is a fun case! The gist of what this is doing is
732
733
// that we want callers and callees to always agree on the
@@ -758,12 +759,22 @@ fn fn_abi_adjust_for_abi<'tcx>(
758
759
}
759
760
// Compute `Aggregate` ABI.
760
761
761
- let is_indirect_not_on_stack =
762
- matches ! ( arg. mode, PassMode :: Indirect { on_stack: false , .. } ) ;
763
- assert ! ( is_indirect_not_on_stack, "{:?}" , arg) ;
762
+ let is_indirect_not_on_stack = ! matches ! ( arg . layout . abi , Abi :: Aggregate { .. } )
763
+ || matches ! ( arg. mode, PassMode :: Indirect { on_stack: false , .. } ) ;
764
+ assert ! ( is_indirect_not_on_stack, "is_indirect_not_on_stack: {:?}" , arg) ;
764
765
765
766
let size = arg. layout . size ;
766
- if !arg. layout . is_unsized ( ) && size <= Pointer ( AddressSpace :: DATA ) . size ( cx) {
767
+ let ptr_size = Pointer ( AddressSpace :: DATA ) . size ( cx) ;
768
+
769
+ // In x86 we may return 2x pointer sized struct as i64
770
+ let reg_struct_return_case = tcx. sess . target . arch == "x86"
771
+ && arg_idx. is_none ( )
772
+ && tcx. sess . opts . unstable_opts . reg_struct_return
773
+ && abi != SpecAbi :: RustIntrinsic ;
774
+
775
+ if !arg. layout . is_unsized ( )
776
+ && ( size <= ptr_size || ( reg_struct_return_case && ( size <= 2 * ptr_size) ) )
777
+ {
767
778
// We want to pass small aggregates as immediates, but using
768
779
// an LLVM aggregate type for this leads to bad optimizations,
769
780
// so we pick an appropriately sized integer type instead.
0 commit comments