@@ -231,7 +231,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
231
231
}
232
232
233
233
PassMode :: Direct ( _) | PassMode :: Pair ( ..) => {
234
- let op = self . codegen_consume ( & bx, & mir:: Place :: Local ( mir:: RETURN_PLACE ) ) ;
234
+ let op = self . codegen_consume ( & bx, & mir:: Place :: local ( mir:: RETURN_PLACE ) ) ;
235
235
if let Ref ( llval, align) = op. val {
236
236
bx. load ( llval, align)
237
237
} else {
@@ -514,16 +514,24 @@ impl FunctionCx<'a, 'll, 'tcx> {
514
514
// checked by const-qualification, which also
515
515
// promotes any complex rvalues to constants.
516
516
if i == 2 && intrinsic. unwrap ( ) . starts_with ( "simd_shuffle" ) {
517
- match * arg {
517
+ match arg {
518
518
// The shuffle array argument is usually not an explicit constant,
519
519
// but specified directly in the code. This means it gets promoted
520
520
// and we can then extract the value by evaluating the promoted.
521
- mir:: Operand :: Copy ( mir:: Place :: Promoted ( box( index, ty) ) ) |
522
- mir:: Operand :: Move ( mir:: Place :: Promoted ( box( index, ty) ) ) => {
521
+ mir:: Operand :: Copy ( mir:: Place {
522
+ base : mir:: PlaceBase :: Promoted ( box ( index, ty) ) ,
523
+ elems,
524
+ } ) |
525
+ mir:: Operand :: Move ( mir:: Place {
526
+ base : mir:: PlaceBase :: Promoted ( box ( index, ty) ) ,
527
+ elems,
528
+ } )
529
+ if elems. is_empty ( )
530
+ => {
523
531
let param_env = ty:: ParamEnv :: reveal_all ( ) ;
524
532
let cid = mir:: interpret:: GlobalId {
525
533
instance : self . instance ,
526
- promoted : Some ( index) ,
534
+ promoted : Some ( * index) ,
527
535
} ;
528
536
let c = bx. tcx ( ) . const_eval ( param_env. and ( cid) ) ;
529
537
let ( llval, ty) = self . simd_shuffle_indices (
@@ -817,37 +825,42 @@ impl FunctionCx<'a, 'll, 'tcx> {
817
825
if fn_ret. is_ignore ( ) {
818
826
return ReturnDest :: Nothing ;
819
827
}
820
- let dest = if let mir:: Place :: Local ( index) = * dest {
821
- match self . locals [ index] {
822
- LocalRef :: Place ( dest) => dest,
823
- LocalRef :: Operand ( None ) => {
824
- // Handle temporary places, specifically Operand ones, as
825
- // they don't have allocas
826
- return if fn_ret. is_indirect ( ) {
827
- // Odd, but possible, case, we have an operand temporary,
828
- // but the calling convention has an indirect return.
829
- let tmp = PlaceRef :: alloca ( bx, fn_ret. layout , "tmp_ret" ) ;
830
- tmp. storage_live ( bx) ;
831
- llargs. push ( tmp. llval ) ;
832
- ReturnDest :: IndirectOperand ( tmp, index)
833
- } else if is_intrinsic {
834
- // Currently, intrinsics always need a location to store
835
- // the result. so we create a temporary alloca for the
836
- // result
837
- let tmp = PlaceRef :: alloca ( bx, fn_ret. layout , "tmp_ret" ) ;
838
- tmp. storage_live ( bx) ;
839
- ReturnDest :: IndirectOperand ( tmp, index)
840
- } else {
841
- ReturnDest :: DirectOperand ( index)
842
- } ;
843
- }
844
- LocalRef :: Operand ( Some ( _) ) => {
845
- bug ! ( "place local already assigned to" ) ;
828
+ let dest = match dest {
829
+ mir:: Place {
830
+ base : mir:: PlaceBase :: Local ( index) ,
831
+ elems,
832
+ } if elems. is_empty ( ) => {
833
+ match self . locals [ * index] {
834
+ LocalRef :: Place ( dest) => dest,
835
+ LocalRef :: Operand ( None ) => {
836
+ // Handle temporary places, specifically Operand ones, as
837
+ // they don't have allocas
838
+ return if fn_ret. is_indirect ( ) {
839
+ // Odd, but possible, case, we have an operand temporary,
840
+ // but the calling convention has an indirect return.
841
+ let tmp = PlaceRef :: alloca ( bx, fn_ret. layout , "tmp_ret" ) ;
842
+ tmp. storage_live ( bx) ;
843
+ llargs. push ( tmp. llval ) ;
844
+ ReturnDest :: IndirectOperand ( tmp, * index)
845
+ } else if is_intrinsic {
846
+ // Currently, intrinsics always need a location to store
847
+ // the result. so we create a temporary alloca for the
848
+ // result
849
+ let tmp = PlaceRef :: alloca ( bx, fn_ret. layout , "tmp_ret" ) ;
850
+ tmp. storage_live ( bx) ;
851
+ ReturnDest :: IndirectOperand ( tmp, * index)
852
+ } else {
853
+ ReturnDest :: DirectOperand ( * index)
854
+ } ;
855
+ }
856
+ LocalRef :: Operand ( Some ( _) ) => {
857
+ bug ! ( "place local already assigned to" ) ;
858
+ }
846
859
}
847
860
}
848
- } else {
849
- self . codegen_place ( bx, dest)
861
+ _ => self . codegen_place ( bx, dest) ,
850
862
} ;
863
+
851
864
if fn_ret. is_indirect ( ) {
852
865
if dest. align . abi ( ) < dest. layout . align . abi ( ) {
853
866
// Currently, MIR code generation does not create calls
@@ -868,27 +881,33 @@ impl FunctionCx<'a, 'll, 'tcx> {
868
881
fn codegen_transmute ( & mut self , bx : & Builder < ' a , ' ll , ' tcx > ,
869
882
src : & mir:: Operand < ' tcx > ,
870
883
dst : & mir:: Place < ' tcx > ) {
871
- if let mir:: Place :: Local ( index) = * dst {
872
- match self . locals [ index] {
873
- LocalRef :: Place ( place) => self . codegen_transmute_into ( bx, src, place) ,
874
- LocalRef :: Operand ( None ) => {
875
- let dst_layout = bx. cx . layout_of ( self . monomorphized_place_ty ( dst) ) ;
876
- assert ! ( !dst_layout. ty. has_erasable_regions( ) ) ;
877
- let place = PlaceRef :: alloca ( bx, dst_layout, "transmute_temp" ) ;
878
- place. storage_live ( bx) ;
879
- self . codegen_transmute_into ( bx, src, place) ;
880
- let op = place. load ( bx) ;
881
- place. storage_dead ( bx) ;
882
- self . locals [ index] = LocalRef :: Operand ( Some ( op) ) ;
883
- }
884
- LocalRef :: Operand ( Some ( op) ) => {
885
- assert ! ( op. layout. is_zst( ) ,
886
- "assigning to initialized SSAtemp" ) ;
884
+ match dst {
885
+ mir:: Place {
886
+ base : mir:: PlaceBase :: Local ( index) ,
887
+ elems,
888
+ } if elems. is_empty ( ) => {
889
+ match self . locals [ * index] {
890
+ LocalRef :: Place ( place) => self . codegen_transmute_into ( bx, src, place) ,
891
+ LocalRef :: Operand ( None ) => {
892
+ let dst_layout = bx. cx . layout_of ( self . monomorphized_place_ty ( dst) ) ;
893
+ assert ! ( !dst_layout. ty. has_erasable_regions( ) ) ;
894
+ let place = PlaceRef :: alloca ( bx, dst_layout, "transmute_temp" ) ;
895
+ place. storage_live ( bx) ;
896
+ self . codegen_transmute_into ( bx, src, place) ;
897
+ let op = place. load ( bx) ;
898
+ place. storage_dead ( bx) ;
899
+ self . locals [ * index] = LocalRef :: Operand ( Some ( op) ) ;
900
+ }
901
+ LocalRef :: Operand ( Some ( op) ) => {
902
+ assert ! ( op. layout. is_zst( ) ,
903
+ "assigning to initialized SSAtemp" ) ;
904
+ }
887
905
}
888
906
}
889
- } else {
890
- let dst = self . codegen_place ( bx, dst) ;
891
- self . codegen_transmute_into ( bx, src, dst) ;
907
+ _ => {
908
+ let dst = self . codegen_place ( bx, dst) ;
909
+ self . codegen_transmute_into ( bx, src, dst) ;
910
+ }
892
911
}
893
912
}
894
913
0 commit comments