@@ -91,7 +91,9 @@ use std::hash::{Hash, Hasher};
9191
9292use either:: Either ;
9393use itertools:: Itertools as _;
94- use rustc_abi:: { self as abi, BackendRepr , FIRST_VARIANT , FieldIdx , Primitive , Size , VariantIdx } ;
94+ use rustc_abi:: {
95+ self as abi, BackendRepr , FIRST_VARIANT , FieldIdx , Integer , Primitive , Size , VariantIdx ,
96+ } ;
9597use rustc_arena:: DroplessArena ;
9698use rustc_const_eval:: const_eval:: DummyMachine ;
9799use rustc_const_eval:: interpret:: {
@@ -108,7 +110,7 @@ use rustc_middle::bug;
108110use rustc_middle:: mir:: interpret:: { AllocRange , GlobalAlloc } ;
109111use rustc_middle:: mir:: visit:: * ;
110112use rustc_middle:: mir:: * ;
111- use rustc_middle:: ty:: layout:: HasTypingEnv ;
113+ use rustc_middle:: ty:: layout:: { HasTypingEnv , IntegerExt } ;
112114use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
113115use rustc_span:: DUMMY_SP ;
114116use smallvec:: SmallVec ;
@@ -1482,6 +1484,33 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
14821484 ( BinOp :: Eq , a, b) if a == b => self . insert_bool ( true ) ,
14831485 ( BinOp :: Ne , Left ( a) , Left ( b) ) => self . insert_bool ( a != b) ,
14841486 ( BinOp :: Ne , a, b) if a == b => self . insert_bool ( false ) ,
1487+ // When casting from a value, and comparing with a literal
1488+ // compare the maximum value with this literal
1489+ // to see if it's possible omit the runtime check
1490+ ( BinOp :: Lt , Right ( a) , Left ( b) ) if self . max_value_of_cast ( a) . is_some_and ( |a| a < b) => {
1491+ self . insert_bool ( true )
1492+ }
1493+ ( BinOp :: Lt , Left ( a) , Right ( b) ) if self . max_value_of_cast ( b) . is_some_and ( |b| a >= b) => {
1494+ self . insert_bool ( false )
1495+ }
1496+ ( BinOp :: Le , Right ( a) , Left ( b) ) if self . max_value_of_cast ( a) . is_some_and ( |a| a <= b) => {
1497+ self . insert_bool ( true )
1498+ }
1499+ ( BinOp :: Le , Left ( a) , Right ( b) ) if self . max_value_of_cast ( b) . is_some_and ( |b| a > b) => {
1500+ self . insert_bool ( false )
1501+ }
1502+ ( BinOp :: Gt , Left ( a) , Right ( b) ) if self . max_value_of_cast ( b) . is_some_and ( |b| a > b) => {
1503+ self . insert_bool ( true )
1504+ }
1505+ ( BinOp :: Gt , Right ( a) , Left ( b) ) if self . max_value_of_cast ( a) . is_some_and ( |a| a <= b) => {
1506+ self . insert_bool ( false )
1507+ }
1508+ ( BinOp :: Ge , Left ( a) , Right ( b) ) if self . max_value_of_cast ( b) . is_some_and ( |b| a >= b) => {
1509+ self . insert_bool ( true )
1510+ }
1511+ ( BinOp :: Ge , Right ( a) , Left ( b) ) if self . max_value_of_cast ( a) . is_some_and ( |a| a < b) => {
1512+ self . insert_bool ( false )
1513+ }
14851514 _ => return None ,
14861515 } ;
14871516
@@ -1494,6 +1523,16 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
14941523 }
14951524 }
14961525
1526+ fn max_value_of_cast ( & self , value : VnIndex ) -> Option < u128 > {
1527+ if let Value :: Cast { kind : CastKind :: IntToInt , value } = self . get ( value) {
1528+ self . max_value_of_cast ( value)
1529+ } else if let ty:: Uint ( uty) = self . ty ( value) . kind ( ) {
1530+ Some ( Integer :: from_uint_ty ( & self . tcx , * uty) . size ( ) . unsigned_int_max ( ) )
1531+ } else {
1532+ None
1533+ }
1534+ }
1535+
14971536 fn simplify_cast (
14981537 & mut self ,
14991538 initial_kind : & mut CastKind ,
0 commit comments