Skip to content

Commit eccf064

Browse files
committed
Flatten control-flow in inline_asm_call after verification
1 parent b630029 commit eccf064

File tree

1 file changed

+53
-52
lines changed
  • compiler/rustc_codegen_llvm/src

1 file changed

+53
-52
lines changed

compiler/rustc_codegen_llvm/src/asm.rs

+53-52
Original file line numberDiff line numberDiff line change
@@ -476,66 +476,67 @@ pub(crate) fn inline_asm_call<'ll>(
476476

477477
debug!("Asm Output Type: {:?}", output);
478478
let fty = bx.cx.type_func(&argtys, output);
479+
479480
// Ask LLVM to verify that the constraints are well-formed.
480481
let constraints_ok = unsafe { llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr(), cons.len()) };
481482
debug!("constraint verification result: {:?}", constraints_ok);
482-
if constraints_ok {
483-
let v = unsafe {
484-
llvm::LLVMGetInlineAsm(
485-
fty,
486-
asm.as_ptr(),
487-
asm.len(),
488-
cons.as_ptr(),
489-
cons.len(),
490-
volatile,
491-
alignstack,
492-
dia,
493-
can_throw,
494-
)
495-
};
483+
if !constraints_ok {
484+
// LLVM has detected an issue with our constraints, so bail out.
485+
return None;
486+
}
496487

497-
let call = if !labels.is_empty() {
498-
assert!(catch_funclet.is_none());
499-
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None)
500-
} else if let Some((catch, funclet)) = catch_funclet {
501-
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None)
502-
} else {
503-
bx.call(fty, None, None, v, inputs, None, None)
504-
};
488+
let v = unsafe {
489+
llvm::LLVMGetInlineAsm(
490+
fty,
491+
asm.as_ptr(),
492+
asm.len(),
493+
cons.as_ptr(),
494+
cons.len(),
495+
volatile,
496+
alignstack,
497+
dia,
498+
can_throw,
499+
)
500+
};
505501

506-
// Store mark in a metadata node so we can map LLVM errors
507-
// back to source locations. See #17552.
508-
let key = "srcloc";
509-
let kind = bx.get_md_kind_id(key);
502+
let call = if !labels.is_empty() {
503+
assert!(catch_funclet.is_none());
504+
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None)
505+
} else if let Some((catch, funclet)) = catch_funclet {
506+
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None)
507+
} else {
508+
bx.call(fty, None, None, v, inputs, None, None)
509+
};
510510

511-
// `srcloc` contains one 64-bit integer for each line of assembly code,
512-
// where the lower 32 bits hold the lo byte position and the upper 32 bits
513-
// hold the hi byte position.
514-
let mut srcloc = vec![];
515-
if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
516-
// LLVM inserts an extra line to add the ".intel_syntax", so add
517-
// a dummy srcloc entry for it.
518-
//
519-
// Don't do this if we only have 1 line span since that may be
520-
// due to the asm template string coming from a macro. LLVM will
521-
// default to the first srcloc for lines that don't have an
522-
// associated srcloc.
523-
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0)));
524-
}
525-
srcloc.extend(line_spans.iter().map(|span| {
526-
llvm::LLVMValueAsMetadata(
527-
bx.const_u64(u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32)),
528-
)
529-
}));
530-
let md = unsafe { llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len()) };
531-
let md = bx.get_metadata_value(md);
532-
llvm::LLVMSetMetadata(call, kind, md);
511+
// Store mark in a metadata node so we can map LLVM errors
512+
// back to source locations. See #17552.
513+
let key = "srcloc";
514+
let kind = bx.get_md_kind_id(key);
533515

534-
Some(call)
535-
} else {
536-
// LLVM has detected an issue with our constraints, bail out
537-
None
516+
// `srcloc` contains one 64-bit integer for each line of assembly code,
517+
// where the lower 32 bits hold the lo byte position and the upper 32 bits
518+
// hold the hi byte position.
519+
let mut srcloc = vec![];
520+
if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
521+
// LLVM inserts an extra line to add the ".intel_syntax", so add
522+
// a dummy srcloc entry for it.
523+
//
524+
// Don't do this if we only have 1 line span since that may be
525+
// due to the asm template string coming from a macro. LLVM will
526+
// default to the first srcloc for lines that don't have an
527+
// associated srcloc.
528+
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0)));
538529
}
530+
srcloc.extend(line_spans.iter().map(|span| {
531+
llvm::LLVMValueAsMetadata(
532+
bx.const_u64(u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32)),
533+
)
534+
}));
535+
let md = unsafe { llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len()) };
536+
let md = bx.get_metadata_value(md);
537+
llvm::LLVMSetMetadata(call, kind, md);
538+
539+
Some(call)
539540
}
540541

541542
/// If the register is an xmm/ymm/zmm register then return its index.

0 commit comments

Comments
 (0)