@@ -28,7 +28,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
28
28
options : InlineAsmOptions ,
29
29
line_spans : & [ Span ] ,
30
30
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 > ) > ,
32
33
) {
33
34
let asm_arch = self . tcx . sess . asm_arch . unwrap ( ) ;
34
35
@@ -165,6 +166,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
165
166
}
166
167
167
168
// Build the template string
169
+ let mut labels = vec ! [ ] ;
168
170
let mut template_str = String :: new ( ) ;
169
171
for piece in template {
170
172
match * piece {
@@ -205,6 +207,11 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
205
207
// Only emit the raw symbol name
206
208
template_str. push_str ( & format ! ( "${{{}:c}}" , op_idx[ & operand_idx] ) ) ;
207
209
}
210
+ InlineAsmOperandRef :: Label { label } => {
211
+ template_str. push_str ( & format ! ( "${{{}:l}}" , constraints. len( ) ) ) ;
212
+ constraints. push ( "!i" . to_owned ( ) ) ;
213
+ labels. push ( label) ;
214
+ }
208
215
}
209
216
}
210
217
}
@@ -292,12 +299,14 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
292
299
& constraints. join ( "," ) ,
293
300
& inputs,
294
301
output_type,
302
+ & labels,
295
303
volatile,
296
304
alignstack,
297
305
dialect,
298
306
line_spans,
299
307
options. contains ( InlineAsmOptions :: MAY_UNWIND ) ,
300
- dest_catch_funclet,
308
+ dest,
309
+ catch_funclet,
301
310
)
302
311
. unwrap_or_else ( || span_bug ! ( line_spans[ 0 ] , "LLVM asm constraint validation failed" ) ) ;
303
312
@@ -317,7 +326,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
317
326
attributes:: apply_to_callsite ( result, llvm:: AttributePlace :: Function , & { attrs } ) ;
318
327
319
328
// 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 {
321
330
self . switch_to_block ( dest) ;
322
331
}
323
332
@@ -415,16 +424,14 @@ pub(crate) fn inline_asm_call<'ll>(
415
424
cons : & str ,
416
425
inputs : & [ & ' ll Value ] ,
417
426
output : & ' ll llvm:: Type ,
427
+ labels : & [ & ' ll llvm:: BasicBlock ] ,
418
428
volatile : bool ,
419
429
alignstack : bool ,
420
430
dia : llvm:: AsmDialect ,
421
431
line_spans : & [ Span ] ,
422
432
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 > > ) > ,
428
435
) -> Option < & ' ll Value > {
429
436
let volatile = if volatile { llvm:: True } else { llvm:: False } ;
430
437
let alignstack = if alignstack { llvm:: True } else { llvm:: False } ;
@@ -457,8 +464,10 @@ pub(crate) fn inline_asm_call<'ll>(
457
464
can_throw,
458
465
) ;
459
466
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)
462
471
} else {
463
472
bx. call ( fty, None , None , v, inputs, None )
464
473
} ;
0 commit comments