@@ -1482,6 +1482,33 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
14821482 ( BinOp :: Eq , a, b) if a == b => self . insert_bool ( true ) ,
14831483 ( BinOp :: Ne , Left ( a) , Left ( b) ) => self . insert_bool ( a != b) ,
14841484 ( BinOp :: Ne , a, b) if a == b => self . insert_bool ( false ) ,
1485+ // When casting from a value, and comparing with a literal
1486+ // compare the maximum value with this literal
1487+ // to see if it's possible omit the runtime check
1488+ ( BinOp :: Lt , Right ( a) , Left ( b) ) if self . max_value_of_cast ( a) . is_some_and ( |a| a < b) => {
1489+ self . insert_bool ( true )
1490+ }
1491+ ( BinOp :: Lt , Left ( a) , Right ( b) ) if self . max_value_of_cast ( b) . is_some_and ( |b| b >= a) => {
1492+ self . insert_bool ( false )
1493+ }
1494+ ( BinOp :: Le , Right ( a) , Left ( b) ) if self . max_value_of_cast ( a) . is_some_and ( |a| a <= b) => {
1495+ self . insert_bool ( true )
1496+ }
1497+ ( BinOp :: Le , Left ( a) , Right ( b) ) if self . max_value_of_cast ( b) . is_some_and ( |b| a > b) => {
1498+ self . insert_bool ( false )
1499+ }
1500+ ( BinOp :: Gt , Left ( a) , Right ( b) ) if self . max_value_of_cast ( b) . is_some_and ( |b| a > b) => {
1501+ self . insert_bool ( true )
1502+ }
1503+ ( BinOp :: Gt , Right ( a) , Left ( b) ) if self . max_value_of_cast ( a) . is_some_and ( |a| a <= b) => {
1504+ self . insert_bool ( false )
1505+ }
1506+ ( BinOp :: Ge , Left ( a) , Right ( b) ) if self . max_value_of_cast ( b) . is_some_and ( |b| a >= b) => {
1507+ self . insert_bool ( true )
1508+ }
1509+ ( BinOp :: Ge , Right ( a) , Left ( b) ) if self . max_value_of_cast ( a) . is_some_and ( |a| a < b) => {
1510+ self . insert_bool ( false )
1511+ }
14851512 _ => return None ,
14861513 } ;
14871514
@@ -1494,6 +1521,22 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
14941521 }
14951522 }
14961523
1524+ fn max_value_of_cast ( & self , value : VnIndex ) -> Option < u128 > {
1525+ let Value :: Cast { kind : CastKind :: IntToInt , value } = self . get ( value) else {
1526+ return None ;
1527+ } ;
1528+ let max_value = match self . ty ( value) . kind ( ) {
1529+ ty:: Uint ( ty:: UintTy :: U8 ) => u8:: MAX as u128 ,
1530+ ty:: Uint ( ty:: UintTy :: U16 ) => u16:: MAX as u128 ,
1531+ ty:: Uint ( ty:: UintTy :: U32 ) => u32:: MAX as u128 ,
1532+ ty:: Uint ( ty:: UintTy :: U64 ) => u64:: MAX as u128 ,
1533+ ty:: Uint ( ty:: UintTy :: Usize ) => usize:: MAX as u128 ,
1534+ // u128::MAX intentionally omitted
1535+ _ => return None ,
1536+ } ;
1537+ Some ( max_value)
1538+ }
1539+
14971540 fn simplify_cast (
14981541 & mut self ,
14991542 initial_kind : & mut CastKind ,
0 commit comments