@@ -56,6 +56,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5656
5757 match expr. kind {
5858 ExprKind :: LogicalOp { op : LogicalOp :: And , lhs, rhs } => {
59+ // cold_branch == true is equivalent to unlikely(lhs && rhs)
60+ // cold_branch == false is equivalent to likely(lhs && rhs)
61+ // We propagate the expectation to the lhs and rhs operands as follows:
62+ // likely(lhs && rhs) => likely(lhs) && likely(rhs)
63+ // unlikely(lhs && rhs) => lhs && unlikely(rhs)
64+ // Note that the `unlikely` propagation may be incorrect. With the information
65+ // available, we can't tell which of the operands in unlikely.
66+
5967 let lhs_then_block = unpack ! ( this. then_else_break(
6068 block,
6169 lhs,
@@ -64,8 +72,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
6472 variable_source_info,
6573 declare_bindings,
6674 match cold_branch {
67- Some ( false ) => Some ( false ) ,
68- _ => None ,
75+ Some ( false ) => Some ( false ) , // propagate likely
76+ _ => None , // but not unlikely
6977 } ,
7078 ) ) ;
7179
@@ -76,12 +84,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7684 break_scope,
7785 variable_source_info,
7886 declare_bindings,
79- cold_branch,
87+ cold_branch, // propagate both likely and unlikely
8088 ) ) ;
8189
8290 rhs_then_block. unit ( )
8391 }
8492 ExprKind :: LogicalOp { op : LogicalOp :: Or , lhs, rhs } => {
93+ // cold_branch == true is equivalent to unlikely(lhs || rhs)
94+ // cold_branch == false is equivalent to likely(lhs || rhs)
95+ // We propagate the expectation to the lhs and rhs operands as follows:
96+ // likely(lhs || rhs) => lhs || likely(rhs)
97+ // unlikely(lhs || rhs) => unlikely(lhs) && unlikely(rhs)
98+ // Note that the `likely` propagation may be incorrect. With the information
99+ // available, we can't tell which of the operands in likely.
100+
85101 let local_scope = this. local_scope ( ) ;
86102 let ( lhs_success_block, failure_block) =
87103 this. in_if_then_scope ( local_scope, expr_span, |this| {
@@ -93,8 +109,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
93109 variable_source_info,
94110 true ,
95111 match cold_branch {
96- Some ( true ) => Some ( true ) ,
97- _ => None ,
112+ Some ( true ) => Some ( true ) , // propagate unlikely
113+ _ => None , // but not likely
98114 } ,
99115 )
100116 } ) ;
@@ -105,7 +121,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
105121 break_scope,
106122 variable_source_info,
107123 true ,
108- cold_branch,
124+ cold_branch, // propagate both likely and unlikely
109125 ) ) ;
110126 this. cfg . goto ( lhs_success_block, variable_source_info, rhs_success_block) ;
111127 rhs_success_block. unit ( )
@@ -126,7 +142,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
126142 local_scope,
127143 variable_source_info,
128144 true ,
129- cold_branch. and_then ( |b| Some ( !b) ) ,
145+ cold_branch. and_then ( |b| Some ( !b) ) , // propagate the opposite of likely/unlikely
130146 )
131147 } ) ;
132148 this. break_for_else ( success_block, break_scope, variable_source_info) ;
0 commit comments