Skip to content

Commit 2e42476

Browse files
authored
Rollup merge of #73033 - Amanieu:asm-tls, r=oli-obk
Fix #[thread_local] statics as asm! sym operands The `asm!` RFC specifies that `#[thread_local]` statics may be used as `sym` operands for inline assembly. This also fixes a regression in the handling of `#[thread_local]` during monomorphization which caused link-time errors with multiple codegen units, most likely introduced by #71192. r? @oli-obk
2 parents a37c32e + 74befd9 commit 2e42476

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
@@ -927,12 +927,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
927927
span_bug!(span, "invalid type for asm sym (fn)");
928928
}
929929
}
930-
mir::InlineAsmOperand::SymStatic { ref value } => {
931-
if let Some(def_id) = value.check_static_ptr(bx.tcx()) {
932-
InlineAsmOperandRef::SymStatic { def_id }
933-
} else {
934-
span_bug!(span, "invalid type for asm sym (static)");
935-
}
930+
mir::InlineAsmOperand::SymStatic { def_id } => {
931+
InlineAsmOperandRef::SymStatic { def_id }
936932
}
937933
})
938934
.collect();

src/librustc_middle/mir/mod.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ pub enum InlineAsmOperand<'tcx> {
12431243
value: Box<Constant<'tcx>>,
12441244
},
12451245
SymStatic {
1246-
value: Box<Constant<'tcx>>,
1246+
def_id: DefId,
12471247
},
12481248
}
12491249

@@ -1639,9 +1639,11 @@ impl<'tcx> TerminatorKind<'tcx> {
16391639
InlineAsmOperand::Const { value } => {
16401640
write!(fmt, "const {:?}", value)?;
16411641
}
1642-
InlineAsmOperand::SymFn { value }
1643-
| InlineAsmOperand::SymStatic { value } => {
1644-
write!(fmt, "sym {:?}", value)?;
1642+
InlineAsmOperand::SymFn { value } => {
1643+
write!(fmt, "sym_fn {:?}", value)?;
1644+
}
1645+
InlineAsmOperand::SymStatic { def_id } => {
1646+
write!(fmt, "sym_static {:?}", def_id)?;
16451647
}
16461648
}
16471649
}

src/librustc_middle/mir/visit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -564,10 +564,10 @@ macro_rules! make_mir_visitor {
564564
);
565565
}
566566
}
567-
InlineAsmOperand::SymFn { value }
568-
| InlineAsmOperand::SymStatic { value } => {
567+
InlineAsmOperand::SymFn { value } => {
569568
self.visit_constant(value, source_location);
570569
}
570+
InlineAsmOperand::SymStatic { def_id: _ } => {}
571571
}
572572
}
573573
}

src/librustc_mir/borrow_check/invalidation.rs

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

src/librustc_mir/borrow_check/mod.rs

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

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
@@ -358,8 +358,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
358358
hair::InlineAsmOperand::SymFn { expr } => {
359359
mir::InlineAsmOperand::SymFn { value: box this.as_constant(expr) }
360360
}
361-
hair::InlineAsmOperand::SymStatic { expr } => {
362-
mir::InlineAsmOperand::SymStatic { value: box this.as_constant(expr) }
361+
hair::InlineAsmOperand::SymStatic { def_id } => {
362+
mir::InlineAsmOperand::SymStatic { def_id }
363363
}
364364
})
365365
.collect();

src/librustc_mir_build/hair/cx/expr.rs

+2-19
Original file line numberDiff line numberDiff line change
@@ -467,25 +467,8 @@ fn make_mirror_unadjusted<'a, 'tcx>(
467467
}
468468
}
469469

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

491474
_ => {

src/librustc_mir_build/hair/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ crate enum InlineAsmOperand<'tcx> {
377377
expr: ExprRef<'tcx>,
378378
},
379379
SymStatic {
380-
expr: ExprRef<'tcx>,
380+
def_id: DefId,
381381
},
382382
}
383383

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)