@@ -197,7 +197,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
197197 // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
198198 let layout_val = self . layout_of ( instance_args. type_at ( 0 ) ) ?;
199199 let val = self . read_scalar ( & args[ 0 ] ) ?;
200- let val_bits = val. to_bits ( layout_val. size ) ?;
200+ let val_bits = val. to_bits ( layout_val. size ) ?; // sign is ignored here
201201
202202 let layout_raw_shift = self . layout_of ( self . tcx . types . u32 ) ?;
203203 let raw_shift = self . read_scalar ( & args[ 1 ] ) ?;
@@ -484,7 +484,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
484484 ret_layout : TyAndLayout < ' tcx > ,
485485 ) -> InterpResult < ' tcx , Scalar < M :: Provenance > > {
486486 assert ! ( layout. ty. is_integral( ) , "invalid type for numeric intrinsic: {}" , layout. ty) ;
487- let bits = val. to_bits ( layout. size ) ?;
487+ let bits = val. to_bits ( layout. size ) ?; // these operations all ignore the sign
488488 let extra = 128 - u128:: from ( layout. size . bits ( ) ) ;
489489 let bits_out = match name {
490490 sym:: ctpop => u128:: from ( bits. count_ones ( ) ) ,
@@ -519,6 +519,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
519519 // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.
520520 // First, check x % y != 0 (or if that computation overflows).
521521 let rem = self . binary_op ( BinOp :: Rem , a, b) ?;
522+ // sign does not matter for 0 test, so `to_bits` is fine
522523 if rem. to_scalar ( ) . to_bits ( a. layout . size ) ? != 0 {
523524 throw_ub_custom ! (
524525 fluent:: const_eval_exact_div_has_remainder,
@@ -545,22 +546,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
545546 self . binary_op ( mir_op. wrapping_to_overflowing ( ) . unwrap ( ) , l, r) ?. to_scalar_pair ( ) ;
546547 Ok ( if overflowed. to_bool ( ) ? {
547548 let size = l. layout . size ;
548- let num_bits = size. bits ( ) ;
549549 if l. layout . abi . is_signed ( ) {
550550 // For signed ints the saturated value depends on the sign of the first
551551 // term since the sign of the second term can be inferred from this and
552552 // the fact that the operation has overflowed (if either is 0 no
553553 // overflow can occur)
554- let first_term: u128 = l. to_scalar ( ) . to_bits ( l. layout . size ) ?;
555- let first_term_positive = first_term & ( 1 << ( num_bits - 1 ) ) == 0 ;
556- if first_term_positive {
554+ let first_term: i128 = l. to_scalar ( ) . to_int ( l. layout . size ) ?;
555+ if first_term >= 0 {
557556 // Negative overflow not possible since the positive first term
558557 // can only increase an (in range) negative term for addition
559- // or corresponding negated positive term for subtraction
558+ // or corresponding negated positive term for subtraction.
560559 Scalar :: from_int ( size. signed_int_max ( ) , size)
561560 } else {
562- // Positive overflow not possible for similar reason
563- // max negative
561+ // Positive overflow not possible for similar reason.
564562 Scalar :: from_int ( size. signed_int_min ( ) , size)
565563 }
566564 } else {
0 commit comments