@@ -223,7 +223,6 @@ enum Value<'tcx> {
223
223
NullaryOp ( NullOp < ' tcx > , Ty < ' tcx > ) ,
224
224
UnaryOp ( UnOp , VnIndex ) ,
225
225
BinaryOp ( BinOp , VnIndex , VnIndex ) ,
226
- CheckedBinaryOp ( BinOp , VnIndex , VnIndex ) , // FIXME get rid of this, work like MIR instead
227
226
Cast {
228
227
kind : CastKind ,
229
228
value : VnIndex ,
@@ -508,17 +507,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
508
507
let val = self . ecx . binary_op ( bin_op, & lhs, & rhs) . ok ( ) ?;
509
508
val. into ( )
510
509
}
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
- }
522
510
Cast { kind, value, from : _, to } => match kind {
523
511
CastKind :: IntToInt | CastKind :: IntToFloat => {
524
512
let value = self . evaluated [ value] . as_ref ( ) ?;
@@ -829,17 +817,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
829
817
let lhs = lhs?;
830
818
let rhs = rhs?;
831
819
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) ;
842
822
}
823
+ Value :: BinaryOp ( op, lhs, rhs)
843
824
}
844
825
Rvalue :: UnaryOp ( op, ref mut arg) => {
845
826
let arg = self . simplify_operand ( arg, location) ?;
@@ -970,7 +951,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
970
951
fn simplify_binary (
971
952
& mut self ,
972
953
op : BinOp ,
973
- checked : bool ,
974
954
lhs_ty : Ty < ' tcx > ,
975
955
lhs : VnIndex ,
976
956
rhs : VnIndex ,
@@ -999,22 +979,39 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
999
979
use Either :: { Left , Right } ;
1000
980
let a = as_bits ( lhs) . map_or ( Right ( lhs) , Left ) ;
1001
981
let b = as_bits ( rhs) . map_or ( Right ( rhs) , Left ) ;
982
+
1002
983
let result = match ( op, a, b) {
1003
984
// 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
+ )
1005
994
| (
1006
995
BinOp :: Add
996
+ | BinOp :: AddWithOverflow
997
+ | BinOp :: AddUnchecked
1007
998
| BinOp :: BitOr
1008
999
| BinOp :: BitXor
1009
1000
| BinOp :: Sub
1001
+ | BinOp :: SubWithOverflow
1002
+ | BinOp :: SubUnchecked
1010
1003
| BinOp :: Offset
1011
1004
| BinOp :: Shl
1012
1005
| BinOp :: Shr ,
1013
1006
Right ( p) ,
1014
1007
Left ( 0 ) ,
1015
1008
)
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,
1018
1015
// Attempt to simplify `x & ALL_ONES` to `x`, with `ALL_ONES` depending on type size.
1019
1016
( BinOp :: BitAnd , Right ( p) , Left ( ones) ) | ( BinOp :: BitAnd , Left ( ones) , Right ( p) )
1020
1017
if ones == layout. size . truncate ( u128:: MAX )
@@ -1023,10 +1020,21 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1023
1020
p
1024
1021
}
1025
1022
// Absorbing elements.
1026
- ( BinOp :: Mul | BinOp :: BitAnd , _, Left ( 0 ) )
1023
+ (
1024
+ BinOp :: Mul | BinOp :: MulWithOverflow | BinOp :: MulUnchecked | BinOp :: BitAnd ,
1025
+ _,
1026
+ Left ( 0 ) ,
1027
+ )
1027
1028
| ( BinOp :: Rem , _, Left ( 1 ) )
1028
1029
| (
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 ,
1030
1038
Left ( 0 ) ,
1031
1039
_,
1032
1040
) => self . insert_scalar ( Scalar :: from_uint ( 0u128 , layout. size ) , lhs_ty) ,
@@ -1038,7 +1046,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1038
1046
self . insert_scalar ( Scalar :: from_uint ( ones, layout. size ) , lhs_ty)
1039
1047
}
1040
1048
// 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
+ {
1042
1052
self . insert_scalar ( Scalar :: from_uint ( 0u128 , layout. size ) , lhs_ty)
1043
1053
}
1044
1054
// Comparison:
@@ -1052,7 +1062,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1052
1062
_ => return None ,
1053
1063
} ;
1054
1064
1055
- if checked {
1065
+ if op . is_overflowing ( ) {
1056
1066
let false_val = self . insert_bool ( false ) ;
1057
1067
Some ( self . insert_tuple ( vec ! [ result, false_val] ) )
1058
1068
} else {
0 commit comments