@@ -28,7 +28,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
2828 options : InlineAsmOptions ,
2929 line_spans : & [ Span ] ,
3030 instance : Instance < ' _ > ,
31- dest_catch_funclet : Option < ( Self :: BasicBlock , Self :: BasicBlock , Option < & Self :: Funclet > ) > ,
31+ dest : Option < Self :: BasicBlock > ,
32+ catch_funclet : Option < ( Self :: BasicBlock , Option < & Self :: Funclet > ) > ,
3233 ) {
3334 let asm_arch = self . tcx . sess . asm_arch . unwrap ( ) ;
3435
@@ -165,6 +166,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
165166 }
166167
167168 // Build the template string
169+ let mut labels = vec ! [ ] ;
168170 let mut template_str = String :: new ( ) ;
169171 for piece in template {
170172 match * piece {
@@ -205,6 +207,11 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
205207 // Only emit the raw symbol name
206208 template_str. push_str ( & format ! ( "${{{}:c}}" , op_idx[ & operand_idx] ) ) ;
207209 }
210+ InlineAsmOperandRef :: Label { label } => {
211+ template_str. push_str ( & format ! ( "${{{}:l}}" , constraints. len( ) ) ) ;
212+ constraints. push ( "!i" . to_owned ( ) ) ;
213+ labels. push ( label) ;
214+ }
208215 }
209216 }
210217 }
@@ -292,12 +299,14 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
292299 & constraints. join ( "," ) ,
293300 & inputs,
294301 output_type,
302+ & labels,
295303 volatile,
296304 alignstack,
297305 dialect,
298306 line_spans,
299307 options. contains ( InlineAsmOptions :: MAY_UNWIND ) ,
300- dest_catch_funclet,
308+ dest,
309+ catch_funclet,
301310 )
302311 . unwrap_or_else ( || span_bug ! ( line_spans[ 0 ] , "LLVM asm constraint validation failed" ) ) ;
303312
@@ -317,7 +326,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
317326 attributes:: apply_to_callsite ( result, llvm:: AttributePlace :: Function , & { attrs } ) ;
318327
319328 // Switch to the 'normal' basic block if we did an `invoke` instead of a `call`
320- if let Some ( ( dest, _ , _ ) ) = dest_catch_funclet {
329+ if let Some ( dest) = dest {
321330 self . switch_to_block ( dest) ;
322331 }
323332
@@ -415,16 +424,14 @@ pub(crate) fn inline_asm_call<'ll>(
415424 cons : & str ,
416425 inputs : & [ & ' ll Value ] ,
417426 output : & ' ll llvm:: Type ,
427+ labels : & [ & ' ll llvm:: BasicBlock ] ,
418428 volatile : bool ,
419429 alignstack : bool ,
420430 dia : llvm:: AsmDialect ,
421431 line_spans : & [ Span ] ,
422432 unwind : bool ,
423- dest_catch_funclet : Option < (
424- & ' ll llvm:: BasicBlock ,
425- & ' ll llvm:: BasicBlock ,
426- Option < & Funclet < ' ll > > ,
427- ) > ,
433+ dest : Option < & ' ll llvm:: BasicBlock > ,
434+ catch_funclet : Option < ( & ' ll llvm:: BasicBlock , Option < & Funclet < ' ll > > ) > ,
428435) -> Option < & ' ll Value > {
429436 let volatile = if volatile { llvm:: True } else { llvm:: False } ;
430437 let alignstack = if alignstack { llvm:: True } else { llvm:: False } ;
@@ -457,8 +464,10 @@ pub(crate) fn inline_asm_call<'ll>(
457464 can_throw,
458465 ) ;
459466
460- let call = if let Some ( ( dest, catch, funclet) ) = dest_catch_funclet {
461- bx. invoke ( fty, None , None , v, inputs, dest, catch, funclet)
467+ let call = if !labels. is_empty ( ) {
468+ bx. callbr ( fty, None , None , v, inputs, dest. unwrap ( ) , labels, None )
469+ } else if let Some ( ( catch, funclet) ) = catch_funclet {
470+ bx. invoke ( fty, None , None , v, inputs, dest. unwrap ( ) , catch, funclet)
462471 } else {
463472 bx. call ( fty, None , None , v, inputs, None )
464473 } ;
0 commit comments