@@ -487,8 +487,8 @@ pub fn codegen_intrinsic_call<'tcx>(
487
487
) ;
488
488
ret. write_cvalue( fx, res) ;
489
489
} ;
490
- _ if intrinsic. starts_with( "saturating_" ) , <T > ( c x , c y ) {
491
- assert_eq!( x . layout( ) . ty, y . layout( ) . ty) ;
490
+ _ if intrinsic. starts_with( "saturating_" ) , <T > ( c lhs , c rhs ) {
491
+ assert_eq!( lhs . layout( ) . ty, rhs . layout( ) . ty) ;
492
492
let bin_op = match intrinsic {
493
493
"saturating_add" => BinOp :: Add ,
494
494
"saturating_sub" => BinOp :: Sub ,
@@ -500,8 +500,8 @@ pub fn codegen_intrinsic_call<'tcx>(
500
500
let checked_res = crate :: num:: trans_checked_int_binop(
501
501
fx,
502
502
bin_op,
503
- x ,
504
- y ,
503
+ lhs ,
504
+ rhs ,
505
505
) ;
506
506
507
507
let ( val, has_overflow) = checked_res. load_scalar_pair( fx) ;
@@ -517,8 +517,18 @@ pub fn codegen_intrinsic_call<'tcx>(
517
517
let val = match ( intrinsic, signed) {
518
518
( "saturating_add" , false ) => codegen_select( & mut fx. bcx, has_overflow, max, val) ,
519
519
( "saturating_sub" , false ) => codegen_select( & mut fx. bcx, has_overflow, min, val) ,
520
- ( "saturating_add" , true ) => unimplemented!( ) ,
521
- ( "saturating_sub" , true ) => unimplemented!( ) ,
520
+ ( "saturating_add" , true ) => {
521
+ let rhs = rhs. load_scalar( fx) ;
522
+ let rhs_ge_zero = fx. bcx. ins( ) . icmp_imm( IntCC :: SignedGreaterThanOrEqual , rhs, 0 ) ;
523
+ let sat_val = codegen_select( & mut fx. bcx, rhs_ge_zero, max, min) ;
524
+ codegen_select( & mut fx. bcx, has_overflow, sat_val, val)
525
+ }
526
+ ( "saturating_sub" , true ) => {
527
+ let rhs = rhs. load_scalar( fx) ;
528
+ let rhs_ge_zero = fx. bcx. ins( ) . icmp_imm( IntCC :: SignedGreaterThanOrEqual , rhs, 0 ) ;
529
+ let sat_val = codegen_select( & mut fx. bcx, rhs_ge_zero, min, max) ;
530
+ codegen_select( & mut fx. bcx, has_overflow, sat_val, val)
531
+ }
522
532
_ => unreachable!( ) ,
523
533
} ;
524
534
0 commit comments