From 5d88d3605339d61c81d16b29a1c01edf771a8fe6 Mon Sep 17 00:00:00 2001 From: Alex Brachet Date: Mon, 5 Dec 2022 06:37:21 +0000 Subject: Don't internalize __llvm_profile_counter_bias Currently, LLVM profiling runtime counter relocation cannot be used by rust during LTO because symbols are being internalized before all symbol information is known. This mode makes LLVM emit a __llvm_profile_counter_bias symbol which is referenced by the profiling initialization, which itself is pulled in by the rust driver here [1]. It is enabled with -Cllvm-args=-runtime-counter-relocation for platforms which are opt-in to this mode like Linux. On these platforms there will be no link error, rather just surprising behavior for a user which request runtime counter relocation. The profiling runtime will not see that symbol go on as if it were never there. On Fuchsia, the profiling runtime must have this symbol which will cause a hard link error. As an aside, I don't have enough context as to why rust's LTO model is how it is. AFAICT, the internalize pass is only safe to run at link time when all symbol information is actually known, this being an example as to why. I think special casing this symbol as a known one that LLVM can emit which should not have it's visbility de-escalated should be fine given how seldom this pattern of defining an undefined symbol to get initilization code pulled in is. From a quick grep, __llvm_profile_runtime is the only symbol that rustc does this for. [1] https://github.com/rust-lang/rust/blob/0265a3e93bf1b89d97cae113ed214954d5c35e22/compiler/rustc_codegen_ssa/src/back/linker.rs#L598 --- src/test/codegen/pgo-counter-bias.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/test/codegen/pgo-counter-bias.rs (limited to 'src/test/codegen') diff --git a/src/test/codegen/pgo-counter-bias.rs b/src/test/codegen/pgo-counter-bias.rs new file mode 100644 index 00000000000..28caa7f4aa3 --- /dev/null +++ b/src/test/codegen/pgo-counter-bias.rs @@ -0,0 +1,10 @@ +// Test that __llvm_profile_counter_bias does not get internalized by lto. + +// ignore-macos -runtime-counter-relocation not honored on Mach-O +// compile-flags: -Cprofile-generate -Cllvm-args=-runtime-counter-relocation -Clto=fat +// needs-profiler-support +// no-prefer-dynamic + +// CHECK: @__llvm_profile_counter_bias = {{.*}}global + +pub fn main() {} -- cgit 1.4.1-3-g733a5 From 6085d330339f6206cc449357db15d94328c207da Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Sun, 11 Dec 2022 17:27:01 -0500 Subject: fix transmutes between pointers in different address spaces --- compiler/rustc_codegen_ssa/src/mir/block.rs | 13 +++++++++---- src/test/codegen/avr/avr-func-addrspace.rs | 24 +++++++++++++++++++++++- 2 files changed, 32 insertions(+), 5 deletions(-) (limited to 'src/test/codegen') diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index f3f5ddb52d6..eb42d4840d5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1810,15 +1810,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match (src.layout.abi, dst.layout.abi) { (abi::Abi::Scalar(src_scalar), abi::Abi::Scalar(dst_scalar)) => { // HACK(eddyb) LLVM doesn't like `bitcast`s between pointers and non-pointers. - if (src_scalar.primitive() == abi::Pointer) - == (dst_scalar.primitive() == abi::Pointer) - { + let src_is_ptr = src_scalar.primitive() == abi::Pointer; + let dst_is_ptr = dst_scalar.primitive() == abi::Pointer; + if src_is_ptr == dst_is_ptr { assert_eq!(src.layout.size, dst.layout.size); // NOTE(eddyb) the `from_immediate` and `to_immediate_scalar` // conversions allow handling `bool`s the same as `u8`s. let src = bx.from_immediate(src.immediate()); - let src_as_dst = bx.bitcast(src, bx.backend_type(dst.layout)); + // LLVM also doesn't like `bitcast`s between pointers in different address spaces. + let src_as_dst = if src_is_ptr { + bx.pointercast(src, bx.backend_type(dst.layout)) + } else { + bx.bitcast(src, bx.backend_type(dst.layout)) + }; Immediate(bx.to_immediate_scalar(src_as_dst, dst_scalar)).store(bx, dst); return; } diff --git a/src/test/codegen/avr/avr-func-addrspace.rs b/src/test/codegen/avr/avr-func-addrspace.rs index cbbcfad3ef4..e9740e30da4 100644 --- a/src/test/codegen/avr/avr-func-addrspace.rs +++ b/src/test/codegen/avr/avr-func-addrspace.rs @@ -9,7 +9,7 @@ // It also validates that functions can be called through function pointers // through traits. -#![feature(no_core, lang_items, unboxed_closures, arbitrary_self_types)] +#![feature(no_core, lang_items, intrinsics, unboxed_closures, arbitrary_self_types)] #![crate_type = "lib"] #![no_core] @@ -49,6 +49,10 @@ pub trait Fn: FnOnce { extern "rust-call" fn call(&self, args: Args) -> Self::Output; } +extern "rust-intrinsic" { + pub fn transmute(src: Src) -> Dst; +} + pub static mut STORAGE_FOO: fn(&usize, &mut u32) -> Result<(), ()> = arbitrary_black_box; pub static mut STORAGE_BAR: u32 = 12; @@ -87,3 +91,21 @@ pub extern "C" fn test() { STORAGE_FOO(&1, &mut buf); } } + +// Validate that we can codegen transmutes between data ptrs and fn ptrs. + +// CHECK: define{{.+}}{{void \(\) addrspace\(1\)\*|ptr addrspace\(1\)}} @transmute_data_ptr_to_fn({{\{\}\*|ptr}}{{.*}} %x) +#[no_mangle] +pub unsafe fn transmute_data_ptr_to_fn(x: *const ()) -> fn() { + // It doesn't matter precisely how this is codegenned (through memory or an addrspacecast), + // as long as it doesn't cause a verifier error by using `bitcast`. + transmute(x) +} + +// CHECK: define{{.+}}{{\{\}\*|ptr}} @transmute_fn_ptr_to_data({{void \(\) addrspace\(1\)\*|ptr addrspace\(1\)}}{{.*}} %x) +#[no_mangle] +pub unsafe fn transmute_fn_ptr_to_data(x: fn()) -> *const () { + // It doesn't matter precisely how this is codegenned (through memory or an addrspacecast), + // as long as it doesn't cause a verifier error by using `bitcast`. + transmute(x) +} -- cgit 1.4.1-3-g733a5