@@ -730,6 +730,14 @@ fn fn_abi_adjust_for_abi<'tcx>(
730730
731731            match  arg. layout . abi  { 
732732                Abi :: Aggregate  {  .. }  => { } 
733+                 Abi :: ScalarPair ( ..)  => { 
734+                     // FIXME: It is strange that small struct optimizations are enabled 
735+                     // for 3-fields and more, but disabled for 2-fields (represented by ScalarPair) 
736+                     // Here 2-fields optimizations are enabled only for return value 
737+                     if  !tcx. sess . opts . unstable_opts . reg_struct_return  || arg_idx. is_some ( )  { 
738+                         return ; 
739+                     } 
740+                 } 
733741
734742                // This is a fun case! The gist of what this is doing is 
735743                // that we want callers and callees to always agree on the 
@@ -761,12 +769,22 @@ fn fn_abi_adjust_for_abi<'tcx>(
761769            } 
762770            // Compute `Aggregate` ABI. 
763771
764-             let  is_indirect_not_on_stack =
765-                 matches ! ( arg. mode,  PassMode :: Indirect  {  on_stack:  false ,  .. } ) ; 
766-             assert ! ( is_indirect_not_on_stack,  "{:?}" ,  arg) ; 
772+             let  is_indirect_not_on_stack = ! matches ! ( arg . layout . abi ,   Abi :: Aggregate   {  ..  } ) 
773+                 ||  matches ! ( arg. mode,  PassMode :: Indirect  {  on_stack:  false ,  .. } ) ; 
774+             assert ! ( is_indirect_not_on_stack,  "is_indirect_not_on_stack:  {:?}" ,  arg) ; 
767775
768776            let  size = arg. layout . size ; 
769-             if  !arg. layout . is_unsized ( )  && size <= Pointer ( AddressSpace :: DATA ) . size ( cx)  { 
777+             let  ptr_size = Pointer ( AddressSpace :: DATA ) . size ( cx) ; 
778+ 
779+             // In x86 we may return 2x pointer sized struct as i64 
780+             let  reg_struct_return_case = tcx. sess . target . arch  == "x86" 
781+                 && arg_idx. is_none ( ) 
782+                 && tcx. sess . opts . unstable_opts . reg_struct_return 
783+                 && abi != SpecAbi :: RustIntrinsic ; 
784+ 
785+             if  !arg. layout . is_unsized ( ) 
786+                 && ( size <= ptr_size || ( reg_struct_return_case && ( size <= 2  *  ptr_size) ) ) 
787+             { 
770788                // We want to pass small aggregates as immediates, but using 
771789                // an LLVM aggregate type for this leads to bad optimizations, 
772790                // so we pick an appropriately sized integer type instead. 
0 commit comments