@@ -191,14 +191,23 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
191
191
192
192
mir:: TerminatorKind :: SwitchInt { ref discr, switch_ty, ref values, ref targets } => {
193
193
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
195
196
let lltrue = llblock ( self , targets[ 0 ] ) ;
196
197
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
+ }
199
206
} 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) ;
202
211
}
203
212
} else {
204
213
let ( otherwise, targets) = targets. split_last ( ) . unwrap ( ) ;
0 commit comments