@@ -309,7 +309,10 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
309309 ) -> ( FlatSet < ScalarInt > , FlatSet < bool > ) {
310310 let left = self . eval_operand ( left, state) ;
311311 let right = self . eval_operand ( right, state) ;
312+
312313 match ( left, right) {
314+ ( FlatSet :: Bottom , _) | ( _, FlatSet :: Bottom ) => ( FlatSet :: Bottom , FlatSet :: Bottom ) ,
315+ // Both sides are known, do the actual computation.
313316 ( FlatSet :: Elem ( left) , FlatSet :: Elem ( right) ) => {
314317 match self . ecx . overflowing_binary_op ( op, & left, & right) {
315318 Ok ( ( Scalar :: Int ( val) , overflow, _) ) => {
@@ -318,11 +321,36 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
318321 _ => ( FlatSet :: Top , FlatSet :: Top ) ,
319322 }
320323 }
321- ( FlatSet :: Bottom , _) | ( _, FlatSet :: Bottom ) => ( FlatSet :: Bottom , FlatSet :: Bottom ) ,
322- ( _, _) => {
323- // Could attempt some algebraic simplifications here.
324- ( FlatSet :: Top , FlatSet :: Top )
324+ // Exactly one side is known, attempt some algebraic simplifications.
325+ ( FlatSet :: Elem ( const_arg) , _) | ( _, FlatSet :: Elem ( const_arg) ) => {
326+ let layout = const_arg. layout ;
327+ if !matches ! ( layout. abi, rustc_target:: abi:: Abi :: Scalar ( ..) ) {
328+ return ( FlatSet :: Top , FlatSet :: Top ) ;
329+ }
330+
331+ let arg_scalar = const_arg. to_scalar ( ) ;
332+ let Ok ( arg_scalar) = arg_scalar. try_to_int ( ) else {
333+ return ( FlatSet :: Top , FlatSet :: Top ) ;
334+ } ;
335+ let Ok ( arg_value) = arg_scalar. to_bits ( layout. size ) else {
336+ return ( FlatSet :: Top , FlatSet :: Top ) ;
337+ } ;
338+
339+ match op {
340+ BinOp :: BitAnd if arg_value == 0 => ( FlatSet :: Elem ( arg_scalar) , FlatSet :: Bottom ) ,
341+ BinOp :: BitOr
342+ if arg_value == layout. size . truncate ( u128:: MAX )
343+ || ( layout. ty . is_bool ( ) && arg_value == 1 ) =>
344+ {
345+ ( FlatSet :: Elem ( arg_scalar) , FlatSet :: Bottom )
346+ }
347+ BinOp :: Mul if layout. ty . is_integral ( ) && arg_value == 0 => {
348+ ( FlatSet :: Elem ( arg_scalar) , FlatSet :: Elem ( false ) )
349+ }
350+ _ => ( FlatSet :: Top , FlatSet :: Top ) ,
351+ }
325352 }
353+ ( FlatSet :: Top , FlatSet :: Top ) => ( FlatSet :: Top , FlatSet :: Top ) ,
326354 }
327355 }
328356
0 commit comments