@@ -15,7 +15,9 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
15
15
use rustc_middle:: ty:: { self , adjustment:: PointerCoercion , Instance , Ty , TyCtxt } ;
16
16
use rustc_session:: config:: OptLevel ;
17
17
use rustc_span:: { Span , DUMMY_SP } ;
18
- use rustc_target:: abi:: { self , FieldIdx , FIRST_VARIANT } ;
18
+ use rustc_target:: abi:: { self , FIRST_VARIANT } ;
19
+
20
+ use arrayvec:: ArrayVec ;
19
21
20
22
impl < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
21
23
#[ instrument( level = "trace" , skip( self , bx) ) ]
@@ -722,25 +724,44 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
722
724
mir:: Rvalue :: Use ( ref operand) => self . codegen_operand ( bx, operand) ,
723
725
mir:: Rvalue :: Repeat ( ..) => {
724
726
// According to `rvalue_creates_operand`, only ZST
725
- // repat rvalues are allowed to be operands.
727
+ // repeat rvalues are allowed to be operands.
726
728
let ty = rvalue. ty ( self . mir , self . cx . tcx ( ) ) ;
727
729
OperandRef :: zero_sized ( self . cx . layout_of ( self . monomorphize ( ty) ) )
728
730
}
729
731
mir:: Rvalue :: Aggregate ( ref kind, ref fields) => {
730
732
let ty = rvalue. ty ( self . mir , self . cx . tcx ( ) ) ;
731
733
let ty = self . monomorphize ( ty) ;
732
- let layout = self . cx . layout_of ( self . monomorphize ( ty ) ) ;
734
+ let layout = self . cx . layout_of ( ty ) ;
733
735
match * * kind {
734
736
_ if layout. is_zst ( ) => OperandRef :: zero_sized ( layout) ,
735
737
mir:: AggregateKind :: Tuple => {
736
- debug_assert_eq ! (
737
- fields. len( ) ,
738
- 2 ,
739
- "We should only get pairs, but got {rvalue:?}"
738
+ debug_assert ! (
739
+ self . cx. is_backend_scalar_pair( layout) ,
740
+ "Expected a scalar pair, but this isn't: {layout:?}" ,
740
741
) ;
741
- let a = self . codegen_operand ( bx, & fields[ FieldIdx :: ZERO ] ) ;
742
- let b = self . codegen_operand ( bx, & fields[ FieldIdx :: from_u32 ( 1 ) ] ) ;
743
- let val = OperandValue :: Pair ( a. immediate ( ) , b. immediate ( ) ) ;
742
+ let mut immediates = ArrayVec :: < Bx :: Value , 2 > :: new ( ) ;
743
+ for ( field_idx, field) in fields. iter_enumerated ( ) {
744
+ let mut push = |v| {
745
+ immediates. try_push ( v) . unwrap_or_else ( |_| {
746
+ bug ! ( "Too many immediates at {field_idx:?} in {layout:?}" )
747
+ } )
748
+ } ;
749
+
750
+ let op = self . codegen_operand ( bx, field) ;
751
+ match op. val {
752
+ OperandValue :: ZeroSized => { }
753
+ OperandValue :: Immediate ( v) => push ( v) ,
754
+ OperandValue :: Pair ( v, w) => {
755
+ push ( v) ;
756
+ push ( w) ;
757
+ }
758
+ OperandValue :: Ref ( _) => {
759
+ bug ! ( "reference operand for field {field_idx:?} in {layout:?}" )
760
+ }
761
+ }
762
+ }
763
+ let [ a, b] = immediates. into_inner ( ) . unwrap ( ) ;
764
+ let val = OperandValue :: Pair ( a, b) ;
744
765
OperandRef { val, layout }
745
766
}
746
767
mir:: AggregateKind :: Adt ( ..) => {
@@ -1070,23 +1091,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1070
1091
let layout = self . cx . spanned_layout_of ( ty, span) ;
1071
1092
layout. is_zst ( )
1072
1093
}
1073
- mir:: Rvalue :: Aggregate ( ref kind, ref fields ) => {
1094
+ mir:: Rvalue :: Aggregate ( ref kind, _ ) => {
1074
1095
let ty = rvalue. ty ( self . mir , self . cx . tcx ( ) ) ;
1075
1096
let ty = self . monomorphize ( ty) ;
1076
1097
let layout = self . cx . spanned_layout_of ( ty, span) ;
1077
1098
match * * kind {
1078
1099
// OperandValue::ZeroSized is easy
1079
1100
_ if layout. is_zst ( ) => true ,
1080
- // 2-Tuple of scalars is an easy scalar pair
1101
+ // If a tuple is a scalar pair, we can grab the immediates from the operands
1081
1102
mir:: AggregateKind :: Tuple => {
1082
- fields. len ( ) == 2
1083
- && self . cx . is_backend_scalar_pair ( layout)
1084
- && fields. iter ( ) . all ( |field| {
1085
- let field_ty = field. ty ( self . mir , self . cx . tcx ( ) ) ;
1086
- let field_ty = self . monomorphize ( field_ty) ;
1087
- let field_layout = self . cx . spanned_layout_of ( field_ty, span) ;
1088
- self . cx . is_backend_immediate ( field_layout)
1089
- } )
1103
+ self . cx . is_backend_scalar_pair ( layout)
1090
1104
}
1091
1105
// If a non-union is transparent, we can pass it along
1092
1106
mir:: AggregateKind :: Adt ( _, _, _, _, None ) => {
0 commit comments