@@ -3,6 +3,7 @@ use std::cmp;
33use rustc_abi:: { BackendRepr , ExternAbi , HasDataLayout , Reg , WrappingRange } ;
44use rustc_ast as ast;
55use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
6+ use rustc_data_structures:: packed:: Pu128 ;
67use rustc_hir:: lang_items:: LangItem ;
78use rustc_middle:: mir:: { self , AssertKind , InlineAsmMacro , SwitchTargets , UnwindTerminateReason } ;
89use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf , ValidityRequirement } ;
@@ -406,6 +407,39 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
406407 let cmp = bx. icmp ( IntPredicate :: IntEQ , discr_value, llval) ;
407408 bx. cond_br_with_expect ( cmp, lltarget, llotherwise, expect) ;
408409 }
410+ } else if target_iter. len ( ) == 2
411+ && self . mir [ targets. otherwise ( ) ] . is_empty_unreachable ( )
412+ && targets. all_values ( ) . contains ( & Pu128 ( 0 ) )
413+ && targets. all_values ( ) . contains ( & Pu128 ( 1 ) )
414+ {
415+ // This is the really common case for `bool`, `Option`, etc.
416+ // By using `trunc nuw` we communicate that other values are
417+ // impossible without needing `switch` or `assume`s.
418+ let true_bb = targets. target_for_value ( 1 ) ;
419+ let false_bb = targets. target_for_value ( 0 ) ;
420+ let true_ll = helper. llbb_with_cleanup ( self , true_bb) ;
421+ let false_ll = helper. llbb_with_cleanup ( self , false_bb) ;
422+
423+ let expected_cond_value = if self . cx . sess ( ) . opts . optimize == OptLevel :: No {
424+ None
425+ } else {
426+ match ( self . cold_blocks [ true_bb] , self . cold_blocks [ false_bb] ) {
427+ // Same coldness, no expectation
428+ ( true , true ) | ( false , false ) => None ,
429+ // Different coldness, expect the non-cold one
430+ ( true , false ) => Some ( false ) ,
431+ ( false , true ) => Some ( true ) ,
432+ }
433+ } ;
434+
435+ let bool_ty = bx. tcx ( ) . types . bool ;
436+ let cond = if switch_ty == bool_ty {
437+ discr_value
438+ } else {
439+ let bool_llty = bx. immediate_backend_type ( bx. layout_of ( bool_ty) ) ;
440+ bx. unchecked_utrunc ( discr_value, bool_llty)
441+ } ;
442+ bx. cond_br_with_expect ( cond, true_ll, false_ll, expected_cond_value) ;
409443 } else if self . cx . sess ( ) . opts . optimize == OptLevel :: No
410444 && target_iter. len ( ) == 2
411445 && self . mir [ targets. otherwise ( ) ] . is_empty_unreachable ( )
0 commit comments