@@ -360,22 +360,6 @@ impl<'tcx> CPlace<'tcx> {
360
360
}
361
361
362
362
pub ( crate ) fn write_cvalue ( self , fx : & mut FunctionCx < ' _ , ' tcx , impl Backend > , from : CValue < ' tcx > ) {
363
- #[ cfg( debug_assertions) ]
364
- {
365
- use cranelift_codegen:: cursor:: { Cursor , CursorPosition } ;
366
- let cur_block = match fx. bcx . cursor ( ) . position ( ) {
367
- CursorPosition :: After ( block) => block,
368
- _ => unreachable ! ( ) ,
369
- } ;
370
- fx. add_comment (
371
- fx. bcx . func . layout . last_inst ( cur_block) . unwrap ( ) ,
372
- format ! ( "write_cvalue: {:?}: {:?} <- {:?}: {:?}" , self . inner( ) , self . layout( ) . ty, from. 0 , from. layout( ) . ty) ,
373
- ) ;
374
- }
375
-
376
- let from_ty = from. layout ( ) . ty ;
377
- let to_ty = self . layout ( ) . ty ;
378
-
379
363
fn assert_assignable < ' tcx > (
380
364
fx : & FunctionCx < ' _ , ' tcx , impl Backend > ,
381
365
from_ty : Ty < ' tcx > ,
@@ -436,12 +420,60 @@ impl<'tcx> CPlace<'tcx> {
436
420
}
437
421
}
438
422
439
- assert_assignable ( fx, from_ty, to_ty) ;
423
+ assert_assignable ( fx, from. layout ( ) . ty , self . layout ( ) . ty ) ;
424
+
425
+ self . write_cvalue_maybe_transmute ( fx, from, "write_cvalue" ) ;
426
+ }
427
+
428
+ pub ( crate ) fn write_cvalue_transmute (
429
+ self ,
430
+ fx : & mut FunctionCx < ' _ , ' tcx , impl Backend > ,
431
+ from : CValue < ' tcx > ,
432
+ ) {
433
+ self . write_cvalue_maybe_transmute ( fx, from, "write_cvalue_transmute" ) ;
434
+ }
435
+
436
+ fn write_cvalue_maybe_transmute (
437
+ self ,
438
+ fx : & mut FunctionCx < ' _ , ' tcx , impl Backend > ,
439
+ from : CValue < ' tcx > ,
440
+ #[ cfg_attr( not( debug_assertions) , allow( unused_variables) ) ]
441
+ method : & ' static str ,
442
+ ) {
443
+ assert_eq ! ( self . layout( ) . size, from. layout( ) . size) ;
444
+
445
+ #[ cfg( debug_assertions) ]
446
+ {
447
+ use cranelift_codegen:: cursor:: { Cursor , CursorPosition } ;
448
+ let cur_block = match fx. bcx . cursor ( ) . position ( ) {
449
+ CursorPosition :: After ( block) => block,
450
+ _ => unreachable ! ( ) ,
451
+ } ;
452
+ fx. add_comment (
453
+ fx. bcx . func . layout . last_inst ( cur_block) . unwrap ( ) ,
454
+ format ! ( "{}: {:?}: {:?} <- {:?}: {:?}" , method, self . inner( ) , self . layout( ) . ty, from. 0 , from. layout( ) . ty) ,
455
+ ) ;
456
+ }
440
457
441
458
let dst_layout = self . layout ( ) ;
442
459
let to_ptr = match self . inner {
443
460
CPlaceInner :: Var ( var) => {
444
461
let data = from. load_scalar ( fx) ;
462
+ let src_ty = fx. bcx . func . dfg . value_type ( data) ;
463
+ let dst_ty = fx. clif_type ( self . layout ( ) . ty ) . unwrap ( ) ;
464
+ let data = match ( src_ty, dst_ty) {
465
+ ( _, _) if src_ty == dst_ty => data,
466
+
467
+ // This is a `write_cvalue_transmute`.
468
+ ( types:: I32 , types:: F32 ) | ( types:: F32 , types:: I32 )
469
+ | ( types:: I64 , types:: F64 ) | ( types:: F64 , types:: I64 ) => {
470
+ fx. bcx . ins ( ) . bitcast ( dst_ty, data)
471
+ }
472
+ _ if src_ty. is_vector ( ) && dst_ty. is_vector ( ) => {
473
+ fx. bcx . ins ( ) . raw_bitcast ( dst_ty, data)
474
+ }
475
+ _ => unreachable ! ( "write_cvalue_transmute: {:?} -> {:?}" , src_ty, dst_ty) ,
476
+ } ;
445
477
fx. bcx . set_val_label ( data, cranelift_codegen:: ir:: ValueLabel :: from_u32 ( var. as_u32 ( ) ) ) ;
446
478
fx. bcx . def_var ( mir_var ( var) , data) ;
447
479
return ;
0 commit comments