Skip to content

Commit

Permalink
Properly handle InlineAsmOperand::SymFn when collecting monomorphized…
Browse files Browse the repository at this point in the history
… items

Fixes #72484
  • Loading branch information
Amanieu committed May 24, 2020
1 parent 215f2d3 commit 3ed1e79
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
3 changes: 1 addition & 2 deletions src/librustc_codegen_ssa/mir/block.rs
Expand Up @@ -908,13 +908,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::InlineAsmOperand::SymFn { ref value } => {
let literal = self.monomorphize(&value.literal);
if let ty::FnDef(def_id, substs) = literal.ty.kind {
let instance = ty::Instance::resolve(
let instance = ty::Instance::resolve_for_fn_ptr(
bx.tcx(),
ty::ParamEnv::reveal_all(),
def_id,
substs,
)
.unwrap()
.unwrap();
InlineAsmOperandRef::SymFn { instance }
} else {
Expand Down
11 changes: 9 additions & 2 deletions src/librustc_mir/monomorphize/collector.rs
Expand Up @@ -633,14 +633,21 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
let ty = self.monomorphize(ty);
visit_drop_use(self.tcx, ty, true, self.output);
}
mir::TerminatorKind::InlineAsm { ref operands, .. } => {
for op in operands {
if let mir::InlineAsmOperand::SymFn { value } = op {
let fn_ty = self.monomorphize(value.literal.ty);
visit_fn_use(self.tcx, fn_ty, false, &mut self.output);
}
}
}
mir::TerminatorKind::Goto { .. }
| mir::TerminatorKind::SwitchInt { .. }
| mir::TerminatorKind::Resume
| mir::TerminatorKind::Abort
| mir::TerminatorKind::Return
| mir::TerminatorKind::Unreachable
| mir::TerminatorKind::Assert { .. }
| mir::TerminatorKind::InlineAsm { .. } => {}
| mir::TerminatorKind::Assert { .. } => {}
mir::TerminatorKind::GeneratorDrop
| mir::TerminatorKind::Yield { .. }
| mir::TerminatorKind::FalseEdges { .. }
Expand Down
38 changes: 38 additions & 0 deletions src/test/ui/asm/sym.rs
@@ -0,0 +1,38 @@
// no-system-llvm
// only-x86_64
// run-pass

#![feature(asm, track_caller)]

extern "C" fn f1() -> i32 {
111
}

// The compiler will generate a shim to hide the caller location parameter.
#[track_caller]
fn f2() -> i32 {
222
}

macro_rules! call {
($func:path) => {{
let result: i32;
unsafe {
asm!("call {}", sym $func,
out("rax") result,
out("rcx") _, out("rdx") _, out("rdi") _, out("rsi") _,
out("r8") _, out("r9") _, out("r10") _, out("r11") _,
out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _,
out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _,
out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _,
out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _,
);
}
result
}}
}

fn main() {
assert_eq!(call!(f1), 111);
assert_eq!(call!(f2), 222);
}

0 comments on commit 3ed1e79

Please sign in to comment.