@@ -31,7 +31,7 @@ use syntax_pos::Pos;
31
31
32
32
use super :: { MirContext , LocalRef } ;
33
33
use super :: constant:: Const ;
34
- use super :: place:: { Alignment , PlaceRef } ;
34
+ use super :: place:: PlaceRef ;
35
35
use super :: operand:: OperandRef ;
36
36
use super :: operand:: OperandValue :: { Pair , Ref , Immediate } ;
37
37
@@ -216,7 +216,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
216
216
PassMode :: Direct ( _) | PassMode :: Pair ( ..) => {
217
217
let op = self . trans_consume ( & bcx, & mir:: Place :: Local ( mir:: RETURN_PLACE ) ) ;
218
218
if let Ref ( llval, align) = op. val {
219
- bcx. load ( llval, align . non_abi ( ) )
219
+ bcx. load ( llval, Some ( align ) )
220
220
} else {
221
221
op. immediate_or_packed_pair ( & bcx)
222
222
}
@@ -228,7 +228,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
228
228
LocalRef :: Operand ( None ) => bug ! ( "use of return before def" ) ,
229
229
LocalRef :: Place ( tr_place) => {
230
230
OperandRef {
231
- val : Ref ( tr_place. llval , tr_place. alignment ) ,
231
+ val : Ref ( tr_place. llval , tr_place. align ) ,
232
232
layout : tr_place. layout
233
233
}
234
234
}
@@ -240,7 +240,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
240
240
scratch. llval
241
241
}
242
242
Ref ( llval, align) => {
243
- assert_eq ! ( align, Alignment :: AbiAligned ,
243
+ assert_eq ! ( align. abi ( ) , op . layout . align . abi ( ) ,
244
244
"return place is unaligned!" ) ;
245
245
llval
246
246
}
@@ -579,7 +579,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
579
579
( & mir:: Operand :: Constant ( _) , Ref ( ..) ) => {
580
580
let tmp = PlaceRef :: alloca ( & bcx, op. layout , "const" ) ;
581
581
op. val . store ( & bcx, tmp) ;
582
- op. val = Ref ( tmp. llval , tmp. alignment ) ;
582
+ op. val = Ref ( tmp. llval , tmp. align ) ;
583
583
}
584
584
_ => { }
585
585
}
@@ -639,38 +639,40 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
639
639
PassMode :: Indirect ( _) | PassMode :: Cast ( _) => {
640
640
let scratch = PlaceRef :: alloca ( bcx, arg. layout , "arg" ) ;
641
641
op. val . store ( bcx, scratch) ;
642
- ( scratch. llval , Alignment :: AbiAligned , true )
642
+ ( scratch. llval , scratch . align , true )
643
643
}
644
644
_ => {
645
- ( op. immediate_or_packed_pair ( bcx) , Alignment :: AbiAligned , false )
645
+ ( op. immediate_or_packed_pair ( bcx) , arg . layout . align , false )
646
646
}
647
647
}
648
648
}
649
- Ref ( llval, align @ Alignment :: Packed ( _) ) if arg. is_indirect ( ) => {
650
- // `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I
651
- // think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't
652
- // have scary latent bugs around.
653
-
654
- let scratch = PlaceRef :: alloca ( bcx, arg. layout , "arg" ) ;
655
- base:: memcpy_ty ( bcx, scratch. llval , llval, op. layout , align. non_abi ( ) ) ;
656
- ( scratch. llval , Alignment :: AbiAligned , true )
649
+ Ref ( llval, align) => {
650
+ if arg. is_indirect ( ) && align. abi ( ) < arg. layout . align . abi ( ) {
651
+ // `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I
652
+ // think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't
653
+ // have scary latent bugs around.
654
+
655
+ let scratch = PlaceRef :: alloca ( bcx, arg. layout , "arg" ) ;
656
+ base:: memcpy_ty ( bcx, scratch. llval , llval, op. layout , Some ( align) ) ;
657
+ ( scratch. llval , scratch. align , true )
658
+ } else {
659
+ ( llval, align, true )
660
+ }
657
661
}
658
- Ref ( llval, align) => ( llval, align, true )
659
662
} ;
660
663
661
664
if by_ref && !arg. is_indirect ( ) {
662
665
// Have to load the argument, maybe while casting it.
663
666
if let PassMode :: Cast ( ty) = arg. mode {
664
667
llval = bcx. load ( bcx. pointercast ( llval, ty. llvm_type ( bcx. ccx ) . ptr_to ( ) ) ,
665
- ( align | Alignment :: Packed ( arg. layout . align ) )
666
- . non_abi ( ) ) ;
668
+ Some ( align. min ( arg. layout . align ) ) ) ;
667
669
} else {
668
670
// We can't use `PlaceRef::load` here because the argument
669
671
// may have a type we don't treat as immediate, but the ABI
670
672
// used for this call is passing it by-value. In that case,
671
673
// the load would just produce `OperandValue::Ref` instead
672
674
// of the `OperandValue::Immediate` we need for the call.
673
- llval = bcx. load ( llval, align . non_abi ( ) ) ;
675
+ llval = bcx. load ( llval, Some ( align ) ) ;
674
676
if let layout:: Abi :: Scalar ( ref scalar) = arg. layout . abi {
675
677
if scalar. is_bool ( ) {
676
678
bcx. range_metadata ( llval, 0 ..2 ) ;
@@ -820,21 +822,17 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
820
822
self . trans_place ( bcx, dest)
821
823
} ;
822
824
if fn_ret. is_indirect ( ) {
823
- match dest. alignment {
824
- Alignment :: AbiAligned => {
825
- llargs. push ( dest. llval ) ;
826
- ReturnDest :: Nothing
827
- } ,
828
- Alignment :: Packed ( _) => {
829
- // Currently, MIR code generation does not create calls
830
- // that store directly to fields of packed structs (in
831
- // fact, the calls it creates write only to temps),
832
- //
833
- // If someone changes that, please update this code path
834
- // to create a temporary.
835
- span_bug ! ( self . mir. span, "can't directly store to unaligned value" ) ;
836
- }
825
+ if dest. align . abi ( ) < dest. layout . align . abi ( ) {
826
+ // Currently, MIR code generation does not create calls
827
+ // that store directly to fields of packed structs (in
828
+ // fact, the calls it creates write only to temps),
829
+ //
830
+ // If someone changes that, please update this code path
831
+ // to create a temporary.
832
+ span_bug ! ( self . mir. span, "can't directly store to unaligned value" ) ;
837
833
}
834
+ llargs. push ( dest. llval ) ;
835
+ ReturnDest :: Nothing
838
836
} else {
839
837
ReturnDest :: Store ( dest)
840
838
}
@@ -874,8 +872,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
874
872
let llty = src. layout . llvm_type ( bcx. ccx ) ;
875
873
let cast_ptr = bcx. pointercast ( dst. llval , llty. ptr_to ( ) ) ;
876
874
let align = src. layout . align . min ( dst. layout . align ) ;
877
- src. val . store ( bcx,
878
- PlaceRef :: new_sized ( cast_ptr, src. layout , Alignment :: Packed ( align) ) ) ;
875
+ src. val . store ( bcx, PlaceRef :: new_sized ( cast_ptr, src. layout , align) ) ;
879
876
}
880
877
881
878
0 commit comments