@@ -319,7 +319,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
319319 targets : & SwitchTargets ,
320320 ) {
321321 let discr = self . codegen_operand ( bx, discr) ;
322+ let discr_value = discr. immediate ( ) ;
322323 let switch_ty = discr. layout . ty ;
324+ // If our discriminant is a constant we can branch directly
325+ if let Some ( const_discr) = bx. const_to_opt_u128 ( discr_value, false ) {
326+ let target = targets. target_for_value ( const_discr) ;
327+ bx. br ( helper. llbb_with_cleanup ( self , target) ) ;
328+ return ;
329+ } ;
330+
323331 let mut target_iter = targets. iter ( ) ;
324332 if target_iter. len ( ) == 1 {
325333 // If there are two targets (one conditional, one fallback), emit `br` instead of
@@ -330,14 +338,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
330338 if switch_ty == bx. tcx ( ) . types . bool {
331339 // Don't generate trivial icmps when switching on bool.
332340 match test_value {
333- 0 => bx. cond_br ( discr . immediate ( ) , llfalse, lltrue) ,
334- 1 => bx. cond_br ( discr . immediate ( ) , lltrue, llfalse) ,
341+ 0 => bx. cond_br ( discr_value , llfalse, lltrue) ,
342+ 1 => bx. cond_br ( discr_value , lltrue, llfalse) ,
335343 _ => bug ! ( ) ,
336344 }
337345 } else {
338346 let switch_llty = bx. immediate_backend_type ( bx. layout_of ( switch_ty) ) ;
339347 let llval = bx. const_uint_big ( switch_llty, test_value) ;
340- let cmp = bx. icmp ( IntPredicate :: IntEQ , discr . immediate ( ) , llval) ;
348+ let cmp = bx. icmp ( IntPredicate :: IntEQ , discr_value , llval) ;
341349 bx. cond_br ( cmp, lltrue, llfalse) ;
342350 }
343351 } else if self . cx . sess ( ) . opts . optimize == OptLevel :: No
@@ -362,11 +370,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
362370 let ll2 = helper. llbb_with_cleanup ( self , target2) ;
363371 let switch_llty = bx. immediate_backend_type ( bx. layout_of ( switch_ty) ) ;
364372 let llval = bx. const_uint_big ( switch_llty, test_value1) ;
365- let cmp = bx. icmp ( IntPredicate :: IntEQ , discr . immediate ( ) , llval) ;
373+ let cmp = bx. icmp ( IntPredicate :: IntEQ , discr_value , llval) ;
366374 bx. cond_br ( cmp, ll1, ll2) ;
367375 } else {
368376 bx. switch (
369- discr . immediate ( ) ,
377+ discr_value ,
370378 helper. llbb_with_cleanup ( self , targets. otherwise ( ) ) ,
371379 target_iter. map ( |( value, target) | ( value, helper. llbb_with_cleanup ( self , target) ) ) ,
372380 ) ;
0 commit comments