@@ -23,8 +23,8 @@ 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 :: meth;
2627use crate :: traits:: * ;
27- use crate :: { meth, MemFlags } ;
2828
2929// Indicates if we are in the middle of merging a BB's successor into it. This
3030// can happen when BB jumps directly to its successor and the successor has no
@@ -462,7 +462,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
462462 }
463463 }
464464
465- PassMode :: Cast { cast : cast_ty , pad_i32 : _ } => {
465+ PassMode :: Cast { cast, pad_i32 : _ } => {
466466 let op = match self . locals [ mir:: RETURN_PLACE ] {
467467 LocalRef :: Operand ( op) => op,
468468 LocalRef :: PendingOperand => bug ! ( "use of return before def" ) ,
@@ -471,23 +471,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
471471 }
472472 LocalRef :: UnsizedPlace ( _) => bug ! ( "return type must be sized" ) ,
473473 } ;
474- let llslot = match op. val {
475- Immediate ( _) | Pair ( ..) => {
476- let scratch = PlaceRef :: alloca ( bx, self . fn_abi . ret . layout ) ;
477- op. val . store ( bx, scratch) ;
478- scratch. val . llval
479- }
480- Ref ( place_val) => {
481- assert_eq ! (
482- place_val. align, op. layout. align. abi,
483- "return place is unaligned!"
484- ) ;
485- place_val. llval
486- }
487- ZeroSized => bug ! ( "ZST return value shouldn't be in PassMode::Cast" ) ,
488- } ;
489- let ty = bx. cast_backend_type ( cast_ty) ;
490- bx. load ( ty, llslot, self . fn_abi . ret . layout . align . abi )
474+ cast. cast_rust_abi_to_other ( bx, op)
491475 }
492476 } ;
493477 bx. ret ( llval) ;
@@ -1460,10 +1444,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14601444 _ => { }
14611445 }
14621446
1463- // Force by-ref if we have to load through a cast pointer.
1464- let ( mut llval, align, by_ref) = match op. val {
1465- Immediate ( _) | Pair ( ..) => match arg. mode {
1466- PassMode :: Indirect { attrs, .. } => {
1447+ let llval = match arg. mode {
1448+ PassMode :: Indirect { attrs, on_stack, .. } => match op. val {
1449+ Immediate ( _) | Pair ( ..) => {
14671450 // Indirect argument may have higher alignment requirements than the type's alignment.
14681451 // This can happen, e.g. when passing types with <4 byte alignment on the stack on x86.
14691452 let required_align = match attrs. pointee_align {
@@ -1472,17 +1455,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14721455 } ;
14731456 let scratch = PlaceValue :: alloca ( bx, arg. layout . size , required_align) ;
14741457 op. val . store ( bx, scratch. with_type ( arg. layout ) ) ;
1475- ( scratch. llval , scratch. align , true )
1476- }
1477- PassMode :: Cast { .. } => {
1478- let scratch = PlaceRef :: alloca ( bx, arg. layout ) ;
1479- op. val . store ( bx, scratch) ;
1480- ( scratch. val . llval , scratch. val . align , true )
1458+ scratch. llval
14811459 }
1482- _ => ( op. immediate_or_packed_pair ( bx) , arg. layout . align . abi , false ) ,
1483- } ,
1484- Ref ( op_place_val) => match arg. mode {
1485- PassMode :: Indirect { attrs, .. } => {
1460+ Ref ( op_place_val) => {
14861461 let required_align = match attrs. pointee_align {
14871462 Some ( pointee_align) => cmp:: max ( pointee_align, arg. layout . align . abi ) ,
14881463 None => arg. layout . align . abi ,
@@ -1493,15 +1468,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14931468 // to a higher-aligned alloca.
14941469 let scratch = PlaceValue :: alloca ( bx, arg. layout . size , required_align) ;
14951470 bx. typed_place_copy ( scratch, op_place_val, op. layout ) ;
1496- ( scratch. llval , scratch . align , true )
1471+ scratch. llval
14971472 } else {
1498- ( op_place_val. llval , op_place_val . align , true )
1473+ op_place_val. llval
14991474 }
15001475 }
1501- _ => ( op_place_val. llval , op_place_val. align , true ) ,
1502- } ,
1503- ZeroSized => match arg. mode {
1504- PassMode :: Indirect { on_stack, .. } => {
1476+ ZeroSized => {
15051477 if on_stack {
15061478 // It doesn't seem like any target can have `byval` ZSTs, so this assert
15071479 // is here to replace a would-be untested codepath.
@@ -1511,59 +1483,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
15111483 // a pointer for `repr(C)` structs even when empty, so get
15121484 // one from an `alloca` (which can be left uninitialized).
15131485 let scratch = PlaceRef :: alloca ( bx, arg. layout ) ;
1514- ( scratch. val . llval , scratch . val . align , true )
1486+ scratch. val . llval
15151487 }
1516- _ => bug ! ( "ZST {op:?} wasn't ignored, but was passed with abi {arg:?}" ) ,
15171488 } ,
1518- } ;
1519-
1520- if by_ref && !arg. is_indirect ( ) {
1521- // Have to load the argument, maybe while casting it.
1522- if let PassMode :: Cast { cast, pad_i32 : _ } = & arg. mode {
1523- // The ABI mandates that the value is passed as a different struct representation.
1524- // Spill and reload it from the stack to convert from the Rust representation to
1525- // the ABI representation.
1526- let scratch_size = cast. size ( bx) ;
1527- let scratch_align = cast. align ( bx) ;
1528- // Note that the ABI type may be either larger or smaller than the Rust type,
1529- // due to the presence or absence of trailing padding. For example:
1530- // - On some ABIs, the Rust layout { f64, f32, <f32 padding> } may omit padding
1531- // when passed by value, making it smaller.
1532- // - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes
1533- // when passed by value, making it larger.
1534- let copy_bytes = cmp:: min ( cast. unaligned_size ( bx) . bytes ( ) , arg. layout . size . bytes ( ) ) ;
1535- // Allocate some scratch space...
1536- let llscratch = bx. alloca ( scratch_size, scratch_align) ;
1537- bx. lifetime_start ( llscratch, scratch_size) ;
1538- // ...memcpy the value...
1539- bx. memcpy (
1540- llscratch,
1541- scratch_align,
1542- llval,
1543- align,
1544- bx. const_usize ( copy_bytes) ,
1545- MemFlags :: empty ( ) ,
1546- ) ;
1547- // ...and then load it with the ABI type.
1548- let cast_ty = bx. cast_backend_type ( cast) ;
1549- llval = bx. load ( cast_ty, llscratch, scratch_align) ;
1550- bx. lifetime_end ( llscratch, scratch_size) ;
1551- } else {
1552- // We can't use `PlaceRef::load` here because the argument
1553- // may have a type we don't treat as immediate, but the ABI
1554- // used for this call is passing it by-value. In that case,
1555- // the load would just produce `OperandValue::Ref` instead
1556- // of the `OperandValue::Immediate` we need for the call.
1557- llval = bx. load ( bx. backend_type ( arg. layout ) , llval, align) ;
1558- if let abi:: Abi :: Scalar ( scalar) = arg. layout . abi {
1559- if scalar. is_bool ( ) {
1489+ PassMode :: Cast { ref cast, .. } => cast. cast_rust_abi_to_other ( bx, op) ,
1490+ _ => match op. val {
1491+ Immediate ( _) | Pair ( ..) => op. immediate_or_packed_pair ( bx) ,
1492+ Ref ( op_place_val) => {
1493+ // We can't use `PlaceRef::load` here because the argument
1494+ // may have a type we don't treat as immediate, but the ABI
1495+ // used for this call is passing it by-value. In that case,
1496+ // the load would just produce `OperandValue::Ref` instead
1497+ // of the `OperandValue::Immediate` we need for the call.
1498+ let mut llval = bx. load (
1499+ bx. backend_type ( arg. layout ) ,
1500+ op_place_val. llval ,
1501+ op_place_val. align ,
1502+ ) ;
1503+ if let abi:: Abi :: Scalar ( scalar) = arg. layout . abi
1504+ && scalar. is_bool ( )
1505+ {
15601506 bx. range_metadata ( llval, WrappingRange { start : 0 , end : 1 } ) ;
15611507 }
1508+ // We store bools as `i8` so we need to truncate to `i1`.
1509+ llval = bx. to_immediate ( llval, arg. layout ) ;
1510+ llval
15621511 }
1563- // We store bools as `i8` so we need to truncate to `i1`.
1564- llval = bx. to_immediate ( llval, arg. layout ) ;
1565- }
1566- }
1512+ ZeroSized => bug ! ( "ZST {op:?} wasn't ignored, but was passed with abi {arg:?}" ) ,
1513+ } ,
1514+ } ;
15671515
15681516 llargs. push ( llval) ;
15691517 }
0 commit comments