@@ -173,7 +173,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
173173 let ty = instance_args. type_at ( 0 ) ;
174174 let layout = self . layout_of ( ty) ?;
175175 let val = self . read_scalar ( & args[ 0 ] ) ?;
176- let out_val = self . numeric_intrinsic ( intrinsic_name, val, layout) ?;
176+
177+ let out_val = self . numeric_intrinsic ( intrinsic_name, val, layout, dest. layout ) ?;
177178 self . write_scalar ( out_val, dest) ?;
178179 }
179180 sym:: saturating_add | sym:: saturating_sub => {
@@ -200,21 +201,24 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
200201 sym:: rotate_left | sym:: rotate_right => {
201202 // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
202203 // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
203- let layout = self . layout_of ( instance_args. type_at ( 0 ) ) ?;
204+ let layout_val = self . layout_of ( instance_args. type_at ( 0 ) ) ?;
204205 let val = self . read_scalar ( & args[ 0 ] ) ?;
205- let val_bits = val. to_bits ( layout. size ) ?;
206+ let val_bits = val. to_bits ( layout_val. size ) ?;
207+
208+ let layout_raw_shift = self . layout_of ( self . tcx . types . u32 ) ?;
206209 let raw_shift = self . read_scalar ( & args[ 1 ] ) ?;
207- let raw_shift_bits = raw_shift. to_bits ( layout. size ) ?;
208- let width_bits = u128:: from ( layout. size . bits ( ) ) ;
210+ let raw_shift_bits = raw_shift. to_bits ( layout_raw_shift. size ) ?;
211+
212+ let width_bits = u128:: from ( layout_val. size . bits ( ) ) ;
209213 let shift_bits = raw_shift_bits % width_bits;
210214 let inv_shift_bits = ( width_bits - shift_bits) % width_bits;
211215 let result_bits = if intrinsic_name == sym:: rotate_left {
212216 ( val_bits << shift_bits) | ( val_bits >> inv_shift_bits)
213217 } else {
214218 ( val_bits >> shift_bits) | ( val_bits << inv_shift_bits)
215219 } ;
216- let truncated_bits = self . truncate ( result_bits, layout ) ;
217- let result = Scalar :: from_uint ( truncated_bits, layout . size ) ;
220+ let truncated_bits = self . truncate ( result_bits, layout_val ) ;
221+ let result = Scalar :: from_uint ( truncated_bits, layout_val . size ) ;
218222 self . write_scalar ( result, dest) ?;
219223 }
220224 sym:: copy => {
@@ -472,6 +476,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
472476 name : Symbol ,
473477 val : Scalar < M :: Provenance > ,
474478 layout : TyAndLayout < ' tcx > ,
479+ ret_layout : TyAndLayout < ' tcx > ,
475480 ) -> InterpResult < ' tcx , Scalar < M :: Provenance > > {
476481 assert ! ( layout. ty. is_integral( ) , "invalid type for numeric intrinsic: {}" , layout. ty) ;
477482 let bits = val. to_bits ( layout. size ) ?;
@@ -483,11 +488,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
483488 }
484489 sym:: ctlz | sym:: ctlz_nonzero => u128:: from ( bits. leading_zeros ( ) ) - extra,
485490 sym:: cttz | sym:: cttz_nonzero => u128:: from ( ( bits << extra) . trailing_zeros ( ) ) - extra,
486- sym:: bswap => ( bits << extra) . swap_bytes ( ) ,
487- sym:: bitreverse => ( bits << extra) . reverse_bits ( ) ,
491+ sym:: bswap => {
492+ assert_eq ! ( layout, ret_layout) ;
493+ ( bits << extra) . swap_bytes ( )
494+ }
495+ sym:: bitreverse => {
496+ assert_eq ! ( layout, ret_layout) ;
497+ ( bits << extra) . reverse_bits ( )
498+ }
488499 _ => bug ! ( "not a numeric intrinsic: {}" , name) ,
489500 } ;
490- Ok ( Scalar :: from_uint ( bits_out, layout . size ) )
501+ Ok ( Scalar :: from_uint ( bits_out, ret_layout . size ) )
491502 }
492503
493504 pub fn exact_div (
0 commit comments