@@ -23,6 +23,7 @@ use super::{CachedLlbb, FunctionCx, LocalRef};
2323use crate :: base:: { self , is_call_from_compiler_builtins_to_upstream_monomorphization} ;
2424use crate :: common:: { self , IntPredicate } ;
2525use crate :: errors:: CompilerBuiltinsCannotCall ;
26+ use crate :: mir:: IntrinsicResult ;
2627use crate :: traits:: * ;
2728use crate :: { MemFlags , meth} ;
2829
@@ -945,32 +946,31 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
945946 let result_layout =
946947 self . cx . layout_of ( self . monomorphized_place_ty ( destination. as_ref ( ) ) ) ;
947948
948- let ( result, store_in_local) = if result_layout. is_zst ( ) {
949- (
950- PlaceRef :: new_sized ( bx. const_undef ( bx. type_ptr ( ) ) , result_layout) ,
951- None ,
952- )
953- } else if let Some ( local) = destination. as_local ( ) {
954- match self . locals [ local] {
955- LocalRef :: Place ( dest) => ( dest, None ) ,
956- LocalRef :: UnsizedPlace ( _) => bug ! ( "return type must be sized" ) ,
957- LocalRef :: PendingOperand => {
958- // Currently, intrinsics always need a location to store
959- // the result, so we create a temporary `alloca` for the
960- // result.
961- let tmp = PlaceRef :: alloca ( bx, result_layout) ;
962- tmp. storage_live ( bx) ;
963- ( tmp, Some ( local) )
949+ let ( result_place, store_in_local) =
950+ if let Some ( local) = destination. as_local ( ) {
951+ match self . locals [ local] {
952+ LocalRef :: Place ( dest) => ( Some ( dest. val ) , None ) ,
953+ LocalRef :: UnsizedPlace ( _) => bug ! ( "return type must be sized" ) ,
954+ LocalRef :: PendingOperand => ( None , Some ( local) ) ,
955+ LocalRef :: Operand ( _) => {
956+ if result_layout. is_zst ( ) {
957+ let place = PlaceRef :: new_sized (
958+ bx. const_undef ( bx. type_ptr ( ) ) ,
959+ result_layout,
960+ ) ;
961+ ( Some ( place. val ) , None )
962+ } else {
963+ bug ! ( "place local already assigned to" ) ;
964+ }
965+ }
964966 }
965- LocalRef :: Operand ( _) => {
966- bug ! ( "place local already assigned to" ) ;
967- }
968- }
969- } else {
970- ( self . codegen_place ( bx, destination. as_ref ( ) ) , None )
971- } ;
967+ } else {
968+ ( Some ( self . codegen_place ( bx, destination. as_ref ( ) ) . val ) , None )
969+ } ;
972970
973- if result. val . align < result. layout . align . abi {
971+ if let Some ( place) = result_place
972+ && place. align < result_layout. align . abi
973+ {
974974 // Currently, MIR code generation does not create calls
975975 // that store directly to fields of packed structs (in
976976 // fact, the calls it creates write only to temps).
@@ -983,24 +983,45 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
983983 let args: Vec < _ > =
984984 args. iter ( ) . map ( |arg| self . codegen_operand ( bx, & arg. node ) ) . collect ( ) ;
985985
986- match self . codegen_intrinsic_call ( bx, instance, & args, result, source_info)
987- {
988- Ok ( ( ) ) => {
989- if let Some ( local) = store_in_local {
990- let op = bx. load_operand ( result) ;
991- result. storage_dead ( bx) ;
986+ let intrinsic_result = self . codegen_intrinsic_call (
987+ bx,
988+ instance,
989+ & args,
990+ result_layout,
991+ result_place,
992+ source_info,
993+ ) ;
994+
995+ if let IntrinsicResult :: Operand ( op_val) = intrinsic_result {
996+ match ( result_place, store_in_local) {
997+ ( None , Some ( local) ) => {
998+ let op = OperandRef {
999+ val : op_val,
1000+ layout : result_layout,
1001+ move_annotation : None ,
1002+ } ;
9921003 self . overwrite_local ( local, LocalRef :: Operand ( op) ) ;
9931004 self . debug_introduce_local ( bx, local) ;
9941005 }
1006+ ( Some ( place_val) , None ) => {
1007+ let dest = PlaceRef { val : place_val, layout : result_layout } ;
1008+ op_val. store ( bx, dest) ;
1009+ }
1010+ _ => bug ! ( ) ,
1011+ }
1012+ }
9951013
1014+ match intrinsic_result {
1015+ IntrinsicResult :: Operand ( _) | IntrinsicResult :: WroteIntoPlace => {
9961016 return if let Some ( target) = target {
9971017 helper. funclet_br ( self , bx, target, mergeable_succ)
9981018 } else {
9991019 bx. unreachable ( ) ;
10001020 MergingSucc :: False
10011021 } ;
10021022 }
1003- Err ( instance) => {
1023+ IntrinsicResult :: Err ( _) => return MergingSucc :: False ,
1024+ IntrinsicResult :: Fallback ( instance) => {
10041025 if intrinsic. must_be_overridden {
10051026 span_bug ! (
10061027 fn_span,
0 commit comments