@@ -3,6 +3,7 @@ use std::cmp;
3
3
use rustc_abi:: { BackendRepr , ExternAbi , HasDataLayout , Reg , WrappingRange } ;
4
4
use rustc_ast as ast;
5
5
use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
6
+ use rustc_data_structures:: packed:: Pu128 ;
6
7
use rustc_hir:: lang_items:: LangItem ;
7
8
use rustc_middle:: mir:: { self , AssertKind , InlineAsmMacro , SwitchTargets , UnwindTerminateReason } ;
8
9
use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf , ValidityRequirement } ;
@@ -406,6 +407,39 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
406
407
let cmp = bx. icmp ( IntPredicate :: IntEQ , discr_value, llval) ;
407
408
bx. cond_br_with_expect ( cmp, lltarget, llotherwise, expect) ;
408
409
}
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) ;
409
443
} else if self . cx . sess ( ) . opts . optimize == OptLevel :: No
410
444
&& target_iter. len ( ) == 2
411
445
&& self . mir [ targets. otherwise ( ) ] . is_empty_unreachable ( )
0 commit comments