File tree Expand file tree Collapse file tree 2 files changed +12
-7
lines changed
Expand file tree Collapse file tree 2 files changed +12
-7
lines changed Original file line number Diff line number Diff line change @@ -48,6 +48,8 @@ fn main() {
4848 assert_eq ! ( 2.3f32 . copysign( -1.0 ) , -2.3f32 ) ;
4949 println ! ( "{}" , 2.3f32 . powf( 2.0 ) ) ;
5050
51+ assert_eq ! ( i64 :: MAX . checked_mul( 2 ) , None ) ;
52+
5153 assert_eq ! ( -128i8 , ( -128i8 ) . saturating_sub( 1 ) ) ;
5254 assert_eq ! ( 127i8 , 127i8 . saturating_sub( -128 ) ) ;
5355 assert_eq ! ( -128i8 , ( -128i8 ) . saturating_add( -128 ) ) ;
Original file line number Diff line number Diff line change @@ -271,14 +271,17 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
271271 let val_hi = fx. bcx . ins ( ) . umulhi ( lhs, rhs) ;
272272 fx. bcx . ins ( ) . icmp_imm ( IntCC :: NotEqual , val_hi, 0 )
273273 } else {
274+ // Based on LLVM's instruction sequence for compiling
275+ // a.checked_mul(b).is_some() to riscv64gc:
276+ // mulh a2, a0, a1
277+ // mul a0, a0, a1
278+ // srai a0, a0, 63
279+ // xor a0, a0, a2
280+ // snez a0, a0
274281 let val_hi = fx. bcx . ins ( ) . smulhi ( lhs, rhs) ;
275- let not_all_zero = fx. bcx . ins ( ) . icmp_imm ( IntCC :: NotEqual , val_hi, 0 ) ;
276- let not_all_ones = fx. bcx . ins ( ) . icmp_imm (
277- IntCC :: NotEqual ,
278- val_hi,
279- u64:: try_from ( ( 1u128 << ty. bits ( ) ) - 1 ) . unwrap ( ) as i64 ,
280- ) ;
281- fx. bcx . ins ( ) . band ( not_all_zero, not_all_ones)
282+ let val_sign = fx. bcx . ins ( ) . sshr_imm ( val, i64:: from ( ty. bits ( ) - 1 ) ) ;
283+ let xor = fx. bcx . ins ( ) . bxor ( val_hi, val_sign) ;
284+ fx. bcx . ins ( ) . icmp_imm ( IntCC :: NotEqual , xor, 0 )
282285 } ;
283286 ( val, has_overflow)
284287 }
You can’t perform that action at this time.
0 commit comments