rust-legacy-fork icon indicating copy to clipboard operation
rust-legacy-fork copied to clipboard

Cannot compile libcore

Open dylanmckay opened this issue 4 years ago • 5 comments

rustc: /home/dylan/projects/avr-rust/rust/src/llvm-project/llvm/lib/IR/Constants.cpp:1784: static llvm::Constant* llvm::ConstantExpr::getBitCast(llvm::Constant*, llvm::Type*, bool): Assertio
n `CastInst::castIsValid(Instruction::BitCast, C, DstTy) && "Invalid constantexpr bitcast!"' failed.                                                                                          
#0  0x00007fffebbc3ce5 in raise () from /usr/lib/libc.so.6
#1  0x00007fffebbad857 in abort () from /usr/lib/libc.so.6
#2  0x00007fffebbad727 in __assert_fail_base.cold () from /usr/lib/libc.so.6
#3  0x00007fffebbbc426 in __assert_fail () from /usr/lib/libc.so.6
#4  0x00007fffefcf955b in llvm::ConstantExpr::getBitCast (C=0x7fffddb635d8, DstTy=0x7fffe77cc680, OnlyIfReduced=false)
    at /home/dylan/projects/avr-rust/rust/src/llvm-project/llvm/lib/IR/Constants.cpp:1784
#5  0x00007fffefd1ec47 in LLVMConstBitCast (ConstantVal=0x7fffddb635d8, ToType=0x7fffe77cc680) at /home/dylan/projects/avr-rust/rust/src/llvm-project/llvm/lib/IR/Core.cpp:1717
#6  0x00007fffecfa4185 in rustc_codegen_llvm::consts::<impl rustc_codegen_llvm::context::CodegenCx>::const_bitcast (self=<optimized out>, val=0x7fffddb635d8, ty=0x0)
    at src/librustc_codegen_llvm/consts.rs:165
#7  rustc_codegen_llvm::common::<impl rustc_codegen_ssa::traits::consts::ConstMethods for rustc_codegen_llvm::context::CodegenCx>::scalar_to_backend (self=<optimized out>, cv=..., 
    layout=0x7ffff38145a0, llty=0x7fffe77cc680) at src/librustc_codegen_llvm/common.rs:276
#8  0x00007fffece0b606 in rustc_codegen_llvm::consts::const_alloc_to_llvm (cx=0x7fffeb72f868, alloc=0x7fffdd625390) at src/librustc_codegen_llvm/consts.rs:57
#9  0x00007fffecfa6794 in rustc_codegen_llvm::consts::codegen_static_initializer (cx=0x7fffeb72f868, def_id=...) at src/librustc_codegen_llvm/consts.rs:87
#10 rustc_codegen_llvm::consts::<impl rustc_codegen_ssa::traits::statics::StaticMethods for rustc_codegen_llvm::context::CodegenCx>::codegen_static (self=0x7fffeb72f868, def_id=..., 
    is_mutable=false) at src/librustc_codegen_llvm/consts.rs:346
#11 0x00007fffecf9fa2b in <rustc_middle::mir::mono::MonoItem as rustc_codegen_ssa::mono_item::MonoItemExt>::define (self=0x7fffeb72f7f0, cx=0x7fffeb72f868)
    at /home/dylan/projects/avr-rust/rust/src/librustc_codegen_ssa/mono_item.rs:31
#12 0x00007fffeceb069b in rustc_codegen_llvm::base::compile_codegen_unit::module_codegen (tcx=..., cgu_name=...) at src/librustc_codegen_llvm/base.rs:129
#13 0x00007fffeced26a0 in rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl (self=0x7fffeb731998, cx=..., arg=..., no_tcx=false, 
    task=0x7fffeceb0540 <rustc_codegen_llvm::base::compile_codegen_unit::module_codegen>, key=..., create_task=<optimized out>, finish_task_and_alloc_depnode=<optimized out>, 
    hash_result=<optimized out>) at /home/dylan/projects/avr-rust/rust/src/librustc_query_system/dep_graph/graph.rs:303
#14 rustc_query_system::dep_graph::graph::DepGraph<K>::with_task (self=0x7fffeb731998, key=..., cx=..., arg=..., 
    task=0x7fffeceb0540 <rustc_codegen_llvm::base::compile_codegen_unit::module_codegen>, hash_result=<optimized out>)
    at /home/dylan/projects/avr-rust/rust/src/librustc_query_system/dep_graph/graph.rs:200
#15 0x00007fffeceb029b in rustc_codegen_llvm::base::compile_codegen_unit (tcx=..., cgu_name=...) at src/librustc_codegen_llvm/base.rs:108
#16 0x00007fffed025c04 in <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::ExtraBackendMethods>::compile_codegen_unit (self=0x7fffeb730148, tcx=..., 
    cgu_name=...) at src/librustc_codegen_llvm/lib.rs:107
#17 rustc_codegen_ssa::base::codegen_crate (backend=..., tcx=..., metadata=..., need_metadata_module=<optimized out>)
    at /home/dylan/projects/avr-rust/rust/src/librustc_codegen_ssa/base.rs:676
#18 0x00007fffecfdf8f5 in <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate (self=<optimized out>, tcx=..., metadata=..., 
    need_metadata_module=229) at src/librustc_codegen_llvm/lib.rs:257
#19 0x00007fffecbcf5d3 in rustc_interface::passes::start_codegen::{{closure}} () at src/librustc_interface/passes.rs:979
#20 rustc_data_structures::profiling::VerboseTimingGuard::run (f=..., self=...) at /home/dylan/projects/avr-rust/rust/src/librustc_data_structures/profiling.rs:569
#21 rustc_session::utils::<impl rustc_session::session::Session>::time (self=<optimized out>, what=..., f=...) at /home/dylan/projects/avr-rust/rust/src/librustc_session/utils.rs:9
#22 rustc_interface::passes::start_codegen (codegen_backend=..., tcx=..., outputs=0x7fffeb738470) at src/librustc_interface/passes.rs:978
#23 0x00007fffecc1b13a in rustc_interface::queries::Queries::ongoing_codegen::{{closure}}::{{closure}} (tcx=...) at src/librustc_interface/queries.rs:282
#24 rustc_middle::ty::context::tls::enter_global::{{closure}} () at /home/dylan/projects/avr-rust/rust/src/librustc_middle/ty/context.rs:1718
#25 rustc_middle::ty::context::tls::enter_context::{{closure}} () at /home/dylan/projects/avr-rust/rust/src/librustc_middle/ty/context.rs:1695
#26 rustc_middle::ty::context::tls::set_tlv (value=140737143574944, f=...) at /home/dylan/projects/avr-rust/rust/src/librustc_middle/ty/context.rs:1679
#27 rustc_middle::ty::context::tls::enter_context (context=0x7fffeb7311a0, f=...) at /home/dylan/projects/avr-rust/rust/src/librustc_middle/ty/context.rs:1695
#28 rustc_middle::ty::context::tls::enter_global (gcx=0x7fffeb7316f0, f=...) at /home/dylan/projects/avr-rust/rust/src/librustc_middle/ty/context.rs:1718
#29 0x00007fffecbfd802 in rustc_interface::passes::QueryContext::enter (self=0x0, f=...) at src/librustc_interface/passes.rs:710
#30 rustc_interface::queries::Queries::ongoing_codegen::{{closure}} () at src/librustc_interface/queries.rs:273
#31 rustc_interface::queries::Query<T>::compute (self=0x7fffeb7384e8, f=...) at src/librustc_interface/queries.rs:34
#32 rustc_interface::queries::Queries::ongoing_codegen (self=0x7fffeb7316e0) at src/librustc_interface/queries.rs:271
#33 0x00007fffec7edf7d in rustc_driver::run_compiler::{{closure}}::{{closure}} (queries=0x2) at src/librustc_driver/lib.rs:399
#34 rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter (self=0x7fffeb7314d0, f=...) at /home/dylan/projects/avr-rust/rust/src/librustc_interface/queries.rs:385
#35 rustc_driver::run_compiler::{{closure}} (compiler=0x7fffeb7314d0) at src/librustc_driver/lib.rs:289
#36 rustc_interface::interface::run_compiler_in_existing_thread_pool (config=..., f=...) at /home/dylan/projects/avr-rust/rust/src/librustc_interface/interface.rs:199
#37 0x00007fffec8529d4 in rustc_interface::interface::run_compiler::{{closure}} () at /home/dylan/projects/avr-rust/rust/src/librustc_interface/interface.rs:213
#38 rustc_interface::util::spawn_thread_pool::{{closure}}::{{closure}}::{{closure}} () at /home/dylan/projects/avr-rust/rust/src/librustc_interface/util.rs:154
#39 scoped_tls::ScopedKey<T>::set (self=<optimized out>, t=0x7fffeb738570, f=...) at /home/dylan/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-1.0.0/src/lib.rs:137
#40 rustc_interface::util::spawn_thread_pool::{{closure}}::{{closure}} () at /home/dylan/projects/avr-rust/rust/src/librustc_interface/util.rs:150
#41 scoped_tls::ScopedKey<T>::set (self=<optimized out>, t=<optimized out>, f=...) at /home/dylan/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-1.0.0/src/lib.rs:137
#42 rustc_ast::attr::with_globals::{{closure}} () at /home/dylan/projects/avr-rust/rust/src/librustc_ast/attr/mod.rs:44
#43 scoped_tls::ScopedKey<T>::set (self=<optimized out>, t=<optimized out>, f=...) at /home/dylan/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-1.0.0/src/lib.rs:137

dylanmckay avatar Apr 15 '20 06:04 dylanmckay

Hello. As far as I understood, you are maintainer of this project. I think this issue is related to https://github.com/avr-rust/rust/issues/164. Do you have any ideas how to fix it?

Logarithmus avatar Apr 21 '20 21:04 Logarithmus

I've got what I think is the same error, but with a different message—probably because I'm using a no-assertion build of LLVM because of #151:

$ rustup run avr-toolchain cargo xbuild --target avr-atmega328p --release
    Updating crates.io index
   Compiling core v0.0.0 (/Users/gaelan/src/rust/src/libcore)
   Compiling compiler_builtins v0.1.27
   Compiling rustc-std-workspace-core v1.99.0 (/Users/gaelan/src/rust/src/tools/rustc-std-workspace-core)
   Compiling alloc v0.0.0 (/var/folders/48/4qjy_0q122zf0xxr3y0m87w00000gn/T/cargo-xbuild.FNqYTsetvzyU)
Invalid bitcast
i8* bitcast (i1 (i16*, %"fmt::Formatter"*) addrspace(1)* @_ZN4core3ops8function6FnOnce9call_once17hc62b6294245b6a49E to i8*)
LLVM ERROR: Broken module found, compilation aborted!
error: could not compile `core`.

To learn more, run the command again with --verbose.
error: `"/Users/gaelan/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/cargo" "rustc" "-p" "alloc" "--release" "--manifest-path" "/var/folders/48/4qjy_0q122zf0xxr3y0m87w00000gn/T/cargo-xbuild.FNqYTsetvzyU/Cargo.toml" "--target" "avr-atmega328p" "--" "-Z" "force-unstable-if-unmarked"` failed with exit code: Some(101)

I recompiled core with --emit=llvm-ir (full output here), and I think this is the line at fault:

@_ZN4core3fmt12USIZE_MARKER17hdf4f8efe342c80b4E = local_unnamed_addr constant <{ i8*, [0 x i8] }> <{ i8* bitcast (i1 (i16*, %"fmt::Formatter"*) addrspace(1)* @_ZN4core3ops8function6FnOnce9call_once17hc62b6294245b6a49E to i8*), [0 x i8] zeroinitializer }>, align 1

And here's the corresponding code in libcore:

// This guarantees a single stable value for the function pointer associated with
// indices/counts in the formatting infrastructure.
//
// Note that a function defined as such would not be correct as functions are
// always tagged unnamed_addr with the current lowering to LLVM IR, so their
// address is not considered important to LLVM and as such the as_usize cast
// could have been miscompiled. In practice, we never call as_usize on non-usize
// containing data (as a matter of static generation of the formatting
// arguments), so this is merely an additional check.
//
// We primarily want to ensure that the function pointer at `USIZE_MARKER` has
// an address corresponding *only* to functions that also take `&usize` as their
// first argument. The read_volatile here ensures that we can safely ready out a
// usize from the passed reference and that this address does not point at a
// non-usize taking function.
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
static USIZE_MARKER: fn(&usize, &mut Formatter<'_>) -> Result = |ptr, _| {
    // SAFETY: ptr is a reference
    let _v: usize = unsafe { crate::ptr::read_volatile(ptr) };
    loop {}
};

That flies way over my head, but it does seem like some sort of crazy unsafe crap that wouldn't work on a Harvard architecture.

Gaelan avatar Apr 25 '20 02:04 Gaelan

@Gaelan you're exactly right, this will be an address space bug that only affects Harvard architectures.

@Logarithmus This bug is vey similar to https://github.com/avr-rust/rust/issues/143, and will have the same fix.

In summary, AVR functions are placed in address space 1. LLVM mostly does a good job at preserving the address space annotation throughout the optimization process, but occasionally there are issues in LLVM where the address space is mistranslated from 1 -> 0 which will invariably cause these 'invalid cast' errors, where the cast is defined as invalid because the address spaces are not polymorphic with each other (read: a memory access of program memory is obviously not the same as a memory access of data memory, so the cast is unsafe). #143 will have more details.

There are two sources of address space bug - 1) when LLVM loses information during the middle end optimization pipeline, and 2) when Rust emits incorrect IR that has invalid casts from the get-go because there are places in Rustc that will assume all pointers are in address space 0 and create them as such.

This looks like an instance of (2). #143 is also an instance of (2).It is likely that both #165 and #143 originate from the same, unidentified piece of Rustc LLVM lowering logic that is specifying function pointer types in address space 0.

There are two solutions - 1) permanent fix to stop Rustc from losing address space information/making address space assumptions, and 2) hacky workaround to amend the USIZE_MARKER identified by @Gaelan so that Rustc somehow does emit the correct address space.

In #143, we fixed it via method (2) - the hacky workaround by inserting a second cast (with _ types so Rust can fill in the type inference).

dylanmckay avatar May 17 '20 04:05 dylanmckay

/cc #169

shepmaster avatar Jun 13 '20 12:06 shepmaster

Possible fix: https://github.com/rust-lang/rust/pull/73270

I have not verified it with the original reproduction though.

dylanmckay avatar Jun 15 '20 10:06 dylanmckay