Skip to content

Commit 74befd9

Browse files
committed
Fix #[thread_local] statics as asm! sym operands
1 parent 2a5cbb0 commit 74befd9

File tree

11 files changed

+78
-45
lines changed

11 files changed

+78
-45
lines changed

src/librustc_codegen_ssa/mir/block.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -921,12 +921,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
921921
span_bug!(span, "invalid type for asm sym (fn)");
922922
}
923923
}
924-
mir::InlineAsmOperand::SymStatic { ref value } => {
925-
if let Some(def_id) = value.check_static_ptr(bx.tcx()) {
926-
InlineAsmOperandRef::SymStatic { def_id }
927-
} else {
928-
span_bug!(span, "invalid type for asm sym (static)");
929-
}
924+
mir::InlineAsmOperand::SymStatic { def_id } => {
925+
InlineAsmOperandRef::SymStatic { def_id }
930926
}
931927
})
932928
.collect();

src/librustc_middle/mir/mod.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ pub enum InlineAsmOperand<'tcx> {
12401240
value: Box<Constant<'tcx>>,
12411241
},
12421242
SymStatic {
1243-
value: Box<Constant<'tcx>>,
1243+
def_id: DefId,
12441244
},
12451245
}
12461246

@@ -1636,9 +1636,11 @@ impl<'tcx> TerminatorKind<'tcx> {
16361636
InlineAsmOperand::Const { value } => {
16371637
write!(fmt, "const {:?}", value)?;
16381638
}
1639-
InlineAsmOperand::SymFn { value }
1640-
| InlineAsmOperand::SymStatic { value } => {
1641-
write!(fmt, "sym {:?}", value)?;
1639+
InlineAsmOperand::SymFn { value } => {
1640+
write!(fmt, "sym_fn {:?}", value)?;
1641+
}
1642+
InlineAsmOperand::SymStatic { def_id } => {
1643+
write!(fmt, "sym_static {:?}", def_id)?;
16421644
}
16431645
}
16441646
}

src/librustc_middle/mir/visit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -563,10 +563,10 @@ macro_rules! make_mir_visitor {
563563
);
564564
}
565565
}
566-
InlineAsmOperand::SymFn { value }
567-
| InlineAsmOperand::SymStatic { value } => {
566+
InlineAsmOperand::SymFn { value } => {
568567
self.visit_constant(value, source_location);
569568
}
569+
InlineAsmOperand::SymStatic { def_id: _ } => {}
570570
}
571571
}
572572
}

src/librustc_mir/borrow_check/invalidation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
208208
}
209209
}
210210
InlineAsmOperand::SymFn { value: _ }
211-
| InlineAsmOperand::SymStatic { value: _ } => {}
211+
| InlineAsmOperand::SymStatic { def_id: _ } => {}
212212
}
213213
}
214214
}

src/librustc_mir/borrow_check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
759759
}
760760
}
761761
InlineAsmOperand::SymFn { value: _ }
762-
| InlineAsmOperand::SymStatic { value: _ } => {}
762+
| InlineAsmOperand::SymStatic { def_id: _ } => {}
763763
}
764764
}
765765
}

src/librustc_mir/dataflow/move_paths/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
439439
}
440440
}
441441
InlineAsmOperand::SymFn { value: _ }
442-
| InlineAsmOperand::SymStatic { value: _ } => {}
442+
| InlineAsmOperand::SymStatic { def_id: _ } => {}
443443
}
444444
}
445445
}

src/librustc_mir/monomorphize/collector.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -634,9 +634,19 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
634634
}
635635
mir::TerminatorKind::InlineAsm { ref operands, .. } => {
636636
for op in operands {
637-
if let mir::InlineAsmOperand::SymFn { value } = op {
638-
let fn_ty = self.monomorphize(value.literal.ty);
639-
visit_fn_use(self.tcx, fn_ty, false, &mut self.output);
637+
match *op {
638+
mir::InlineAsmOperand::SymFn { ref value } => {
639+
let fn_ty = self.monomorphize(value.literal.ty);
640+
visit_fn_use(self.tcx, fn_ty, false, &mut self.output);
641+
}
642+
mir::InlineAsmOperand::SymStatic { def_id } => {
643+
let instance = Instance::mono(self.tcx, def_id);
644+
if should_monomorphize_locally(self.tcx, &instance) {
645+
trace!("collecting asm sym static {:?}", def_id);
646+
self.output.push(MonoItem::Static(def_id));
647+
}
648+
}
649+
_ => {}
640650
}
641651
}
642652
}

src/librustc_mir_build/build/expr/into.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
353353
hair::InlineAsmOperand::SymFn { expr } => {
354354
mir::InlineAsmOperand::SymFn { value: box this.as_constant(expr) }
355355
}
356-
hair::InlineAsmOperand::SymStatic { expr } => {
357-
mir::InlineAsmOperand::SymStatic { value: box this.as_constant(expr) }
356+
hair::InlineAsmOperand::SymStatic { def_id } => {
357+
mir::InlineAsmOperand::SymStatic { def_id }
358358
}
359359
})
360360
.collect();

src/librustc_mir_build/hair/cx/expr.rs

+2-19
Original file line numberDiff line numberDiff line change
@@ -465,25 +465,8 @@ fn make_mirror_unadjusted<'a, 'tcx>(
465465
}
466466
}
467467

468-
Res::Def(DefKind::Static, id) => {
469-
ty = cx.tcx.static_ptr_ty(id);
470-
let ptr = cx.tcx.create_static_alloc(id);
471-
InlineAsmOperand::SymStatic {
472-
expr: Expr {
473-
ty,
474-
temp_lifetime,
475-
span: expr.span,
476-
kind: ExprKind::StaticRef {
477-
literal: ty::Const::from_scalar(
478-
cx.tcx,
479-
Scalar::Ptr(ptr.into()),
480-
ty,
481-
),
482-
def_id: id,
483-
},
484-
}
485-
.to_ref(),
486-
}
468+
Res::Def(DefKind::Static, def_id) => {
469+
InlineAsmOperand::SymStatic { def_id }
487470
}
488471

489472
_ => {

src/librustc_mir_build/hair/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ crate enum InlineAsmOperand<'tcx> {
374374
expr: ExprRef<'tcx>,
375375
},
376376
SymStatic {
377-
expr: ExprRef<'tcx>,
377+
def_id: DefId,
378378
},
379379
}
380380

src/test/ui/asm/sym.rs

+47-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
// no-system-llvm
22
// only-x86_64
3+
// only-linux
34
// run-pass
45

5-
#![feature(asm, track_caller)]
6+
#![feature(asm, track_caller, thread_local)]
67

78
extern "C" fn f1() -> i32 {
89
111
@@ -15,9 +16,9 @@ fn f2() -> i32 {
1516
}
1617

1718
macro_rules! call {
18-
($func:path) => {{
19-
let result: i32;
19+
($func:path) => {
2020
unsafe {
21+
let result: i32;
2122
asm!("call {}", sym $func,
2223
out("rax") result,
2324
out("rcx") _, out("rdx") _, out("rdi") _, out("rsi") _,
@@ -27,12 +28,53 @@ macro_rules! call {
2728
out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _,
2829
out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _,
2930
);
31+
result
3032
}
31-
result
32-
}}
33+
}
3334
}
3435

36+
macro_rules! static_addr {
37+
($s:expr) => {
38+
unsafe {
39+
let result: *const u32;
40+
// LEA performs a RIP-relative address calculation and returns the address
41+
asm!("lea {}, [rip + {}]", out(reg) result, sym $s);
42+
result
43+
}
44+
}
45+
}
46+
macro_rules! static_tls_addr {
47+
($s:expr) => {
48+
unsafe {
49+
let result: *const u32;
50+
asm!(
51+
"
52+
# Load TLS base address
53+
mov {out}, qword ptr fs:[0]
54+
# Calculate the address of sym in the TLS block. The @tpoff
55+
# relocation gives the offset of the symbol from the start
56+
# of the TLS block.
57+
lea {out}, [{out} + {sym}@tpoff]
58+
",
59+
out = out(reg) result,
60+
sym = sym $s
61+
);
62+
result
63+
}
64+
}
65+
}
66+
67+
static S1: u32 = 111;
68+
#[thread_local]
69+
static S2: u32 = 222;
70+
3571
fn main() {
3672
assert_eq!(call!(f1), 111);
3773
assert_eq!(call!(f2), 222);
74+
assert_eq!(static_addr!(S1), &S1 as *const u32);
75+
assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
76+
std::thread::spawn(|| {
77+
assert_eq!(static_addr!(S1), &S1 as *const u32);
78+
assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
79+
});
3880
}

0 commit comments

Comments
 (0)