@@ -319,7 +319,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
319
319
targets : & SwitchTargets ,
320
320
) {
321
321
let discr = self . codegen_operand ( bx, discr) ;
322
+ let discr_value = discr. immediate ( ) ;
322
323
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
+
323
331
let mut target_iter = targets. iter ( ) ;
324
332
if target_iter. len ( ) == 1 {
325
333
// 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> {
330
338
if switch_ty == bx. tcx ( ) . types . bool {
331
339
// Don't generate trivial icmps when switching on bool.
332
340
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) ,
335
343
_ => bug ! ( ) ,
336
344
}
337
345
} else {
338
346
let switch_llty = bx. immediate_backend_type ( bx. layout_of ( switch_ty) ) ;
339
347
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) ;
341
349
bx. cond_br ( cmp, lltrue, llfalse) ;
342
350
}
343
351
} else if self . cx . sess ( ) . opts . optimize == OptLevel :: No
@@ -362,11 +370,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
362
370
let ll2 = helper. llbb_with_cleanup ( self , target2) ;
363
371
let switch_llty = bx. immediate_backend_type ( bx. layout_of ( switch_ty) ) ;
364
372
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) ;
366
374
bx. cond_br ( cmp, ll1, ll2) ;
367
375
} else {
368
376
bx. switch (
369
- discr . immediate ( ) ,
377
+ discr_value ,
370
378
helper. llbb_with_cleanup ( self , targets. otherwise ( ) ) ,
371
379
target_iter. map ( |( value, target) | ( value, helper. llbb_with_cleanup ( self , target) ) ) ,
372
380
) ;
0 commit comments