@@ -631,12 +631,29 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
631
631
ret. write_cvalue( fx, CValue :: by_val( res, base. layout( ) ) ) ;
632
632
} ;
633
633
634
- transmute, <src_ty, dst_ty> ( c from) {
635
- assert_eq!( from. layout( ) . ty, src_ty) ;
636
- let ( addr, meta) = from. force_stack( fx) ;
637
- assert!( meta. is_none( ) ) ;
638
- let dst_layout = fx. layout_of( dst_ty) ;
639
- ret. write_cvalue( fx, CValue :: by_ref( addr, dst_layout) )
634
+ transmute, ( c from) {
635
+ assert_eq!( from. layout( ) . size, ret. layout( ) . size) ;
636
+ if from. layout( ) . ty. kind == ret. layout( ) . ty. kind {
637
+ ret. write_cvalue( fx, from) ;
638
+ } else if let ( Some ( src_ty) , Some ( dst_ty) ) = ( fx. clif_type( from. layout( ) . ty) , fx. clif_type( ret. layout( ) . ty) ) {
639
+ let from = from. load_scalar( fx) ;
640
+ let val = match ( src_ty, dst_ty) {
641
+ ( _, _) if src_ty == dst_ty => from,
642
+ ( types:: I32 , types:: F32 ) | ( types:: F32 , types:: I32 )
643
+ | ( types:: I64 , types:: F64 ) | ( types:: F64 , types:: I64 ) => {
644
+ fx. bcx. ins( ) . bitcast( dst_ty, from)
645
+ }
646
+ ( _, _) if src_ty. is_vector( ) && dst_ty. is_vector( ) => {
647
+ fx. bcx. ins( ) . raw_bitcast( dst_ty, from)
648
+ }
649
+ _ => unreachable!( "{:?} -> {:?}" , src_ty, dst_ty) ,
650
+ } ;
651
+ ret. write_cvalue( fx, CValue :: by_val( val, ret. layout( ) ) ) ;
652
+ } else {
653
+ let ( addr, meta) = from. force_stack( fx) ;
654
+ assert!( meta. is_none( ) ) ;
655
+ ret. write_cvalue( fx, CValue :: by_ref( addr, ret. layout( ) ) ) ;
656
+ }
640
657
} ;
641
658
write_bytes, ( c dst, v val, v count) {
642
659
let pointee_ty = dst. layout( ) . ty. builtin_deref( true ) . unwrap( ) . ty;
0 commit comments