@@ -191,14 +191,23 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
191191
192192 mir:: TerminatorKind :: SwitchInt { ref discr, switch_ty, ref values, ref targets } => {
193193 let discr = self . codegen_operand ( & bx, discr) ;
194- if switch_ty == bx. tcx ( ) . types . bool {
194+ if targets. len ( ) == 2 {
195+ // If there are two targets, emit br instead of switch
195196 let lltrue = llblock ( self , targets[ 0 ] ) ;
196197 let llfalse = llblock ( self , targets[ 1 ] ) ;
197- if let [ 0 ] = values[ ..] {
198- bx. cond_br ( discr. immediate ( ) , llfalse, lltrue) ;
198+ if switch_ty == bx. tcx ( ) . types . bool {
199+ // Don't generate trivial icmps when switching on bool
200+ if let [ 0 ] = values[ ..] {
201+ bx. cond_br ( discr. immediate ( ) , llfalse, lltrue) ;
202+ } else {
203+ assert_eq ! ( & values[ ..] , & [ 1 ] ) ;
204+ bx. cond_br ( discr. immediate ( ) , lltrue, llfalse) ;
205+ }
199206 } else {
200- assert_eq ! ( & values[ ..] , & [ 1 ] ) ;
201- bx. cond_br ( discr. immediate ( ) , lltrue, llfalse) ;
207+ let switch_llty = bx. cx . layout_of ( switch_ty) . immediate_llvm_type ( bx. cx ) ;
208+ let llval = C_uint_big ( switch_llty, values[ 0 ] ) ;
209+ let cmp = bx. icmp ( llvm:: IntEQ , discr. immediate ( ) , llval) ;
210+ bx. cond_br ( cmp, lltrue, llfalse) ;
202211 }
203212 } else {
204213 let ( otherwise, targets) = targets. split_last ( ) . unwrap ( ) ;
0 commit comments