@@ -223,7 +223,6 @@ enum Value<'tcx> {
223223 NullaryOp ( NullOp < ' tcx > , Ty < ' tcx > ) ,
224224 UnaryOp ( UnOp , VnIndex ) ,
225225 BinaryOp ( BinOp , VnIndex , VnIndex ) ,
226- CheckedBinaryOp ( BinOp , VnIndex , VnIndex ) , // FIXME get rid of this, work like MIR instead
227226 Cast {
228227 kind : CastKind ,
229228 value : VnIndex ,
@@ -508,17 +507,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
508507 let val = self . ecx . binary_op ( bin_op, & lhs, & rhs) . ok ( ) ?;
509508 val. into ( )
510509 }
511- CheckedBinaryOp ( bin_op, lhs, rhs) => {
512- let lhs = self . evaluated [ lhs] . as_ref ( ) ?;
513- let lhs = self . ecx . read_immediate ( lhs) . ok ( ) ?;
514- let rhs = self . evaluated [ rhs] . as_ref ( ) ?;
515- let rhs = self . ecx . read_immediate ( rhs) . ok ( ) ?;
516- let val = self
517- . ecx
518- . binary_op ( bin_op. wrapping_to_overflowing ( ) . unwrap ( ) , & lhs, & rhs)
519- . ok ( ) ?;
520- val. into ( )
521- }
522510 Cast { kind, value, from : _, to } => match kind {
523511 CastKind :: IntToInt | CastKind :: IntToFloat => {
524512 let value = self . evaluated [ value] . as_ref ( ) ?;
@@ -829,17 +817,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
829817 let lhs = lhs?;
830818 let rhs = rhs?;
831819
832- if let Some ( op) = op. overflowing_to_wrapping ( ) {
833- if let Some ( value) = self . simplify_binary ( op, true , ty, lhs, rhs) {
834- return Some ( value) ;
835- }
836- Value :: CheckedBinaryOp ( op, lhs, rhs)
837- } else {
838- if let Some ( value) = self . simplify_binary ( op, false , ty, lhs, rhs) {
839- return Some ( value) ;
840- }
841- Value :: BinaryOp ( op, lhs, rhs)
820+ if let Some ( value) = self . simplify_binary ( op, ty, lhs, rhs) {
821+ return Some ( value) ;
842822 }
823+ Value :: BinaryOp ( op, lhs, rhs)
843824 }
844825 Rvalue :: UnaryOp ( op, ref mut arg) => {
845826 let arg = self . simplify_operand ( arg, location) ?;
@@ -970,7 +951,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
970951 fn simplify_binary (
971952 & mut self ,
972953 op : BinOp ,
973- checked : bool ,
974954 lhs_ty : Ty < ' tcx > ,
975955 lhs : VnIndex ,
976956 rhs : VnIndex ,
@@ -999,22 +979,39 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
999979 use Either :: { Left , Right } ;
1000980 let a = as_bits ( lhs) . map_or ( Right ( lhs) , Left ) ;
1001981 let b = as_bits ( rhs) . map_or ( Right ( rhs) , Left ) ;
982+
1002983 let result = match ( op, a, b) {
1003984 // Neutral elements.
1004- ( BinOp :: Add | BinOp :: BitOr | BinOp :: BitXor , Left ( 0 ) , Right ( p) )
985+ (
986+ BinOp :: Add
987+ | BinOp :: AddWithOverflow
988+ | BinOp :: AddUnchecked
989+ | BinOp :: BitOr
990+ | BinOp :: BitXor ,
991+ Left ( 0 ) ,
992+ Right ( p) ,
993+ )
1005994 | (
1006995 BinOp :: Add
996+ | BinOp :: AddWithOverflow
997+ | BinOp :: AddUnchecked
1007998 | BinOp :: BitOr
1008999 | BinOp :: BitXor
10091000 | BinOp :: Sub
1001+ | BinOp :: SubWithOverflow
1002+ | BinOp :: SubUnchecked
10101003 | BinOp :: Offset
10111004 | BinOp :: Shl
10121005 | BinOp :: Shr ,
10131006 Right ( p) ,
10141007 Left ( 0 ) ,
10151008 )
1016- | ( BinOp :: Mul , Left ( 1 ) , Right ( p) )
1017- | ( BinOp :: Mul | BinOp :: Div , Right ( p) , Left ( 1 ) ) => p,
1009+ | ( BinOp :: Mul | BinOp :: MulWithOverflow | BinOp :: MulUnchecked , Left ( 1 ) , Right ( p) )
1010+ | (
1011+ BinOp :: Mul | BinOp :: MulWithOverflow | BinOp :: MulUnchecked | BinOp :: Div ,
1012+ Right ( p) ,
1013+ Left ( 1 ) ,
1014+ ) => p,
10181015 // Attempt to simplify `x & ALL_ONES` to `x`, with `ALL_ONES` depending on type size.
10191016 ( BinOp :: BitAnd , Right ( p) , Left ( ones) ) | ( BinOp :: BitAnd , Left ( ones) , Right ( p) )
10201017 if ones == layout. size . truncate ( u128:: MAX )
@@ -1023,10 +1020,21 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10231020 p
10241021 }
10251022 // Absorbing elements.
1026- ( BinOp :: Mul | BinOp :: BitAnd , _, Left ( 0 ) )
1023+ (
1024+ BinOp :: Mul | BinOp :: MulWithOverflow | BinOp :: MulUnchecked | BinOp :: BitAnd ,
1025+ _,
1026+ Left ( 0 ) ,
1027+ )
10271028 | ( BinOp :: Rem , _, Left ( 1 ) )
10281029 | (
1029- BinOp :: Mul | BinOp :: Div | BinOp :: Rem | BinOp :: BitAnd | BinOp :: Shl | BinOp :: Shr ,
1030+ BinOp :: Mul
1031+ | BinOp :: MulWithOverflow
1032+ | BinOp :: MulUnchecked
1033+ | BinOp :: Div
1034+ | BinOp :: Rem
1035+ | BinOp :: BitAnd
1036+ | BinOp :: Shl
1037+ | BinOp :: Shr ,
10301038 Left ( 0 ) ,
10311039 _,
10321040 ) => self . insert_scalar ( Scalar :: from_uint ( 0u128 , layout. size ) , lhs_ty) ,
@@ -1038,7 +1046,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10381046 self . insert_scalar ( Scalar :: from_uint ( ones, layout. size ) , lhs_ty)
10391047 }
10401048 // Sub/Xor with itself.
1041- ( BinOp :: Sub | BinOp :: BitXor , a, b) if a == b => {
1049+ ( BinOp :: Sub | BinOp :: SubWithOverflow | BinOp :: SubUnchecked | BinOp :: BitXor , a, b)
1050+ if a == b =>
1051+ {
10421052 self . insert_scalar ( Scalar :: from_uint ( 0u128 , layout. size ) , lhs_ty)
10431053 }
10441054 // Comparison:
@@ -1052,7 +1062,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10521062 _ => return None ,
10531063 } ;
10541064
1055- if checked {
1065+ if op . is_overflowing ( ) {
10561066 let false_val = self . insert_bool ( false ) ;
10571067 Some ( self . insert_tuple ( vec ! [ result, false_val] ) )
10581068 } else {
0 commit comments