@@ -173,7 +173,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
173
173
let ty = instance_args. type_at ( 0 ) ;
174
174
let layout = self . layout_of ( ty) ?;
175
175
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 ) ?;
177
178
self . write_scalar ( out_val, dest) ?;
178
179
}
179
180
sym:: saturating_add | sym:: saturating_sub => {
@@ -200,21 +201,24 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
200
201
sym:: rotate_left | sym:: rotate_right => {
201
202
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
202
203
// 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 ) ) ?;
204
205
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 ) ?;
206
209
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 ( ) ) ;
209
213
let shift_bits = raw_shift_bits % width_bits;
210
214
let inv_shift_bits = ( width_bits - shift_bits) % width_bits;
211
215
let result_bits = if intrinsic_name == sym:: rotate_left {
212
216
( val_bits << shift_bits) | ( val_bits >> inv_shift_bits)
213
217
} else {
214
218
( val_bits >> shift_bits) | ( val_bits << inv_shift_bits)
215
219
} ;
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 ) ;
218
222
self . write_scalar ( result, dest) ?;
219
223
}
220
224
sym:: copy => {
@@ -472,6 +476,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
472
476
name : Symbol ,
473
477
val : Scalar < M :: Provenance > ,
474
478
layout : TyAndLayout < ' tcx > ,
479
+ ret_layout : TyAndLayout < ' tcx > ,
475
480
) -> InterpResult < ' tcx , Scalar < M :: Provenance > > {
476
481
assert ! ( layout. ty. is_integral( ) , "invalid type for numeric intrinsic: {}" , layout. ty) ;
477
482
let bits = val. to_bits ( layout. size ) ?;
@@ -483,11 +488,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
483
488
}
484
489
sym:: ctlz | sym:: ctlz_nonzero => u128:: from ( bits. leading_zeros ( ) ) - extra,
485
490
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
+ }
488
499
_ => bug ! ( "not a numeric intrinsic: {}" , name) ,
489
500
} ;
490
- Ok ( Scalar :: from_uint ( bits_out, layout . size ) )
501
+ Ok ( Scalar :: from_uint ( bits_out, ret_layout . size ) )
491
502
}
492
503
493
504
pub fn exact_div (
0 commit comments