rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.41k stars 12.73k forks source link

Error with -C code-model=large and thread locals #37508

Closed aidanhs closed 3 years ago

aidanhs commented 8 years ago

(allowing specifying code models was added to rustc in https://github.com/rust-lang/rust/pull/15698)

I want to build a large code model binary. But (correct me if I'm wrong) I believe this requires all code to be generated with a large code model (otherwise we could end up with rip relative addressing in the stdlib, which defeats the point).

So I tried the obvious (controlling it with RUSTFLAGS) and got the following build log:

/rust# ./configure && RUSTFLAGS="-C code-model=large" VERBOSE=1 make
[...]
CFG_LLVM_LINKAGE_FILE=/rust/x86_64-unknown-linux-gnu/rt/llvmdeps.rs LD_LIBRARY_PATH=/rust/x86_64-unknown-linux-gnu/stage0/lib:/rust/x86_64-unknown-linux-gnu/llvm/lib:$LD$
LIBRARY_PATH   x86_64-unknown-linux-gnu/stage0/bin/rustc --cfg stage0 -C code-model=large -O --cfg rtopt -C rpath -C prefer-dynamic -C no-stack-check --target=x86_64-unk$
own-linux-gnu   -L "x86_64-unknown-linux-gnu/rt" -L native="/rust/x86_64-unknown-linux-gnu/llvm/lib"     --out-dir x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unk$
own-linux-gnu/lib -C extra-filename=-3d98e1dd -C metadata=3d98e1dd src/librustc_save_analysis/lib.rs
info: now are following matches for librustc_save_analysis-*.so libraries:
x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_save_analysis-3d98e1dd.so
info: now are following matches for librustc_save_analysis-*.rlib libraries:
x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_save_analysis-3d98e1dd.rlib
MATCHES=""; if [ -n "$MATCHES" ] ; then echo "warning: removing previous" \'librustc_driver-*.so\' "libraries:" $MATCHES; rm $MATCHES ; fi
MATCHES=""; if [ -n "$MATCHES" ] ; then echo "warning: removing previous" \'librustc_driver-*.rlib\' "libraries:" $MATCHES; rm $MATCHES ; fi
CFG_LLVM_LINKAGE_FILE=/rust/x86_64-unknown-linux-gnu/rt/llvmdeps.rs LD_LIBRARY_PATH=/rust/x86_64-unknown-linux-gnu/stage0/lib:/rust/x86_64-unknown-linux-gnu/llvm/lib:$LD$
LIBRARY_PATH   x86_64-unknown-linux-gnu/stage0/bin/rustc --cfg stage0 -C code-model=large -O --cfg rtopt -C rpath -C prefer-dynamic -C no-stack-check --target=x86_64-unk$
own-linux-gnu   -L "x86_64-unknown-linux-gnu/rt" -L native="/rust/x86_64-unknown-linux-gnu/llvm/lib"     --out-dir x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unk$
own-linux-gnu/lib -C extra-filename=-3d98e1dd -C metadata=3d98e1dd src/librustc_driver/lib.rs
info: now are following matches for librustc_driver-*.so libraries:
x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_driver-3d98e1dd.so
info: now are following matches for librustc_driver-*.rlib libraries:
x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_driver-3d98e1dd.rlib
mkdir -p x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/bin/
LD_LIBRARY_PATH=/rust/x86_64-unknown-linux-gnu/stage0/lib:/rust/x86_64-unknown-linux-gnu/llvm/lib:$LD_LIBRARY_PATH   x86_64-unknown-linux-gnu/stage0/bin/rustc --cfg stag$
0 -C code-model=large -O --cfg rtopt -C rpath -C prefer-dynamic -C no-stack-check --target=x86_64-unknown-linux-gnu  -L native="/rust/x86_64-unknown-linux-gnu/llvm/lib" $
o x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/bin/rustc /rust/src/driver/driver.rs --cfg rustc
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.core
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.libc
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.rand
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.alloc
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.collections
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.compiler_builtins
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.rustc_unicode
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.alloc_system
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.panic_abort
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.panic_unwind
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.unwind
touch x86_64-unknown-linux-gnu/stage1/lib/stamp.alloc_jemalloc
[...]
cp x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.rustc_save_analysis x86_64-unknown-linux-gnu/stage1/lib/stamp.rustc_save_analysis
cp -R x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_save_analysis-*.so x86_64-unknown-linux-gnu/stage1/lib
info: now are following matches for librustc_save_analysis-*.so libraries:
x86_64-unknown-linux-gnu/stage1/lib/librustc_save_analysis-3d98e1dd.so
MATCHES=""; if [ -n "$MATCHES" ] ; then echo "warning: removing previous" \'librustc_driver-*.so\' "libraries:" $MATCHES; rm $MATCHES ; fi
cp x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.rustc_driver x86_64-unknown-linux-gnu/stage1/lib/stamp.rustc_driver
cp -R x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_driver-*.so x86_64-unknown-linux-gnu/stage1/lib
info: now are following matches for librustc_driver-*.so libraries:
x86_64-unknown-linux-gnu/stage1/lib/librustc_driver-3d98e1dd.so
cp x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/bin/rustc x86_64-unknown-linux-gnu/stage1/bin/rustc
touch tmp/install-debugger-scripts1_H_x86_64-unknown-linux-gnu-all.done.start_time
mkdir -p x86_64-unknown-linux-gnu/stage1/bin
mkdir -p x86_64-unknown-linux-gnu/stage1/lib/rustlib/etc
install  /rust/src/etc/rust-gdb  /rust/src/etc/rust-lldb x86_64-unknown-linux-gnu/stage1/bin
install  /rust/src/etc/gdb_load_rust_pretty_printers.py  /rust/src/etc/gdb_rust_pretty_printing.py  /rust/src/etc/lldb_rust_formatters.py  /rust/src/etc/debugger_pretty_p
rinters_common.py x86_64-unknown-linux-gnu/stage1/lib/rustlib/etc
touch -r tmp/install-debugger-scripts1_H_x86_64-unknown-linux-gnu-all.done.start_time tmp/install-debugger-scripts1_H_x86_64-unknown-linux-gnu-all.done && rm tmp/install-
debugger-scripts1_H_x86_64-unknown-linux-gnu-all.done.start_time
mkdir -p x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib/
MATCHES=""; if [ -n "$MATCHES" ] ; then echo "warning: removing previous" \'libcore-*.so\' "libraries:" $MATCHES; rm $MATCHES ; fi
MATCHES=""; if [ -n "$MATCHES" ] ; then echo "warning: removing previous" \'libcore-*.rlib\' "libraries:" $MATCHES; rm $MATCHES ; fi
CFG_LLVM_LINKAGE_FILE=/rust/x86_64-unknown-linux-gnu/rt/llvmdeps.rs LD_LIBRARY_PATH=/rust/x86_64-unknown-linux-gnu/stage1/lib:/rust/x86_64-unknown-linux-gnu/llvm/lib:$LD_
LIBRARY_PATH   x86_64-unknown-linux-gnu/stage1/bin/rustc --cfg stage1 -C code-model=large -O --cfg rtopt -C rpath -C prefer-dynamic --target=x86_64-unknown-linux-gnu   -L
 "x86_64-unknown-linux-gnu/rt" -L native="/rust/x86_64-unknown-linux-gnu/llvm/lib"     --out-dir x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib 
-C extra-filename=-3d98e1dd -C metadata=3d98e1dd src/libcore/lib.rs
Segmentation fault (core dumped)
/rust/mk/target.mk:191: recipe for target 'x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.core' failed
make: *** [x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib/stamp.core] Error 139

Brief explanation of the three parts:

  1. the command is run
  2. the tail end of the stage1 stdlib and rustc itself being built by stage0
  3. the tail end of the stage1 stdlib and rustc itself being copied out of the stage0 build directory and into the stage1 directory, then the new stage1 rustc attempting to build the first part of the stage2 stdlib (libcore)...and segfaulting

In fact, this stage1 rustc segfaults when not doing much:

/rust# x86_64-unknown-linux-gnu/stage1/bin/rustc --version
rustc 1.14.0-dev (f26eedb57 2016-10-31)
Segmentation fault (core dumped)

Reducing the command line used to build rustc:

/rust# echo 'fn main() {}' > mini.rs
/rust# x86_64-unknown-linux-gnu/stage0/bin/rustc -C code-model=large --target=x86_64-unknown-linux-gnu mini.rs
/rust# ./mini
Segmentation fault (core dumped)
/rust# x86_64-unknown-linux-gnu/stage0/bin/rustc --target=x86_64-unknown-linux-gnu mini.rs
/rust# ./mini
Segmentation fault (core dumped)

GDB gives the backtrace as

#0  0x000055555555f1e0 in std::thread::local::elf::destroy_value::h1727d3182d3ee514 ()
#1  0x00007ffff74115ff in __GI___call_tls_dtors () at cxa_thread_atexit_impl.c:155
#2  0x00007ffff7410f27 in __run_exit_handlers (status=0, listp=0x7ffff779a5f8 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true) at exit.c:40
#3  0x00007ffff7411045 in __GI_exit (status=<optimized out>) at exit.c:104
#4  0x00007ffff73f7837 in __libc_start_main (main=0x55555555dac0 <main>, argc=1, argv=0x7fffffffe7a8, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe798) at ../csu/libc-start.c:325
#5  0x000055555555d9a9 in _start ()

I've dumped a bunch of info in the hope that someone might be able to lend a hand, but I can find little discussion of this feature (code models) so they may not be well-tested? I plan to investigate myself, but wanted a) to see if anyone has any pointers and b) make this a searchable issue.

As a datapoint, note that redox uses a .json target specification and builds its own stdlib manually with kernel model, which obviously works fine. Altering the configure+make command I used to use the kernel model rather than large also worked fine. So it looks like the issue is with memory model large.

aidanhs commented 8 years ago

Compiling mini.rs statically (with glibc, as described at https://github.com/aidanhs/rustnotes) makes it not segfault, which is interesting. Doing --enable-debug in configure also makes it not segfault.

I starting to suspect the issue is in llvm (I don't think anything in the rust compiler itself generates asm?) and rust tickles the bug somehow.

aidanhs commented 8 years ago

Recompiling just the libstd crate without optimisations makes it work.

It appears that

  1. on start thread info is set, which attempts to set a thread local
  2. this calls get on the thread local.
  3. this calls register_dtor, which calls the actual implementation of register_dtor on linux.

By inspection of the parameters passed to __cxa_thread_atexit_impl in the linux implementation of register_dtor with gdb, the t parameter is an invalid pointer (checked by inspecting by /proc/$pid/maps). In theory t should be &self in steps 2 and 3, though the functions look like they've all been inlined.

aidanhs commented 7 years ago

Managed to tear down std to get this test case:

#![no_std]

#![feature(thread_local)]

pub struct BB;

#[thread_local]
static mut KEY: Key = Key {
    inner: BB,
    dtor_running: false,
};

pub unsafe fn set() -> Option<&'static BB> {
    if KEY.dtor_running {
        return None
    }
    Some(&KEY.inner)
}

pub struct Key {
    inner: BB,
    dtor_running: bool,
}
$ rustc lib.rs --crate-type rlib -C opt-level=3 -C code-model=large
rustc: /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/llvm/include/llvm/CodeGen/MachineOperand.h:411: int64_t llvm::MachineOperand::getImm() const: Assertion `isImm() && "Wrong MachineOperand accessor"' failed.

(it seems that since I originally reported this issue, the nightlies now have llvm assertions enabled)

aidanhs commented 7 years ago

Abort seems to be coming from TwoAddressInstructionPass. Backtrace (from gdb) at the point of abort is:

Click to expand backtrace

``` #0 0x00007ffff7383428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 #1 0x00007ffff738502a in __GI_abort () at abort.c:89 #2 0x00007ffff737bbd7 in __assert_fail_base (fmt=, assertion=assertion@entry=0x7ffff3224b18 "isImm() && \"Wrong MachineOperand accessor\"", file=file@entry=0x7ffff3224848 "/home/aidanhs/Desktop/rust/rust-large/src/llvm/include/llvm/CodeGen/MachineOperand.h", line=line@entry=411, function=function@entry=0x7ffff32e4d60 <_ZZNK4llvm14MachineOperand6getImmEvE19__PRETTY_FUNCTION__> "int64_t llvm::MachineOperand::getImm() const") at assert.c:92 #3 0x00007ffff737bc82 in __GI___assert_fail (assertion=assertion@entry=0x7ffff3224b18 "isImm() && \"Wrong MachineOperand accessor\"", file=file@entry=0x7ffff3224848 "/home/aidanhs/Desktop/rust/rust-large/src/llvm/include/llvm/CodeGen/MachineOperand.h", line=line@entry=411, function=function@entry=0x7ffff32e4d60 <_ZZNK4llvm14MachineOperand6getImmEvE19__PRETTY_FUNCTION__> "int64_t llvm::MachineOperand::getImm() const") at assert.c:101 #4 0x00007ffff2195186 in llvm::MachineOperand::getImm (this=) at /home/aidanhs/Desktop/rust/rust-large/src/llvm/include/llvm/CodeGen/MachineOperand.h:411 #5 llvm::X86InstrInfo::convertToThreeAddress (this=0x7fffec222c20, MFI=..., MI=..., LV=0x7fffed541a80) at /home/aidanhs/Desktop/rust/rust-large/src/llvm/lib/Target/X86/X86InstrInfo.cpp:3082 #6 0x00007ffff2881cb7 in (anonymous namespace)::TwoAddressInstructionPass::convertInstTo3Addr (Dist=5, RegB=2147483648, RegA=2147483649, nmi=..., mi=..., this=0x7fffed541c00) at /home/aidanhs/Desktop/rust/rust-large/src/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:707 #7 (anonymous namespace)::TwoAddressInstructionPass::tryInstructionTransform (this=this@entry=0x7fffed541c00, mi=..., nmi=..., SrcIdx=1, DstIdx=, Dist=5, shouldOnlyCommute=false) at /home/aidanhs/Desktop/rust/rust-large/src/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1273 #8 0x00007ffff2885143 in (anonymous namespace)::TwoAddressInstructionPass::runOnMachineFunction (this=, Func=...) at /home/aidanhs/Desktop/rust/rust-large/src/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1686 #9 0x00007ffff2703aa5 in llvm::MachineFunctionPass::runOnFunction (this=0x7fffed541c00, F=...) at /home/aidanhs/Desktop/rust/rust-large/src/llvm/lib/CodeGen/MachineFunctionPass.cpp:60 #10 0x00007ffff2f56ecb in llvm::FPPassManager::runOnFunction (this=0x7fffed4ef880, F=...) at /home/aidanhs/Desktop/rust/rust-large/src/llvm/lib/IR/LegacyPassManager.cpp:1523 #11 0x00007ffff2f572eb in llvm::FPPassManager::runOnModule (this=0x7fffed4ef880, M=...) at /home/aidanhs/Desktop/rust/rust-large/src/llvm/lib/IR/LegacyPassManager.cpp:1544 #12 0x00007ffff2f56acd in (anonymous namespace)::MPPassManager::runOnModule (M=..., this=) at /home/aidanhs/Desktop/rust/rust-large/src/llvm/lib/IR/LegacyPassManager.cpp:1600 #13 llvm::legacy::PassManagerImpl::run (this=0x7fffed4bb300, M=...) at /home/aidanhs/Desktop/rust/rust-large/src/llvm/lib/IR/LegacyPassManager.cpp:1703 #14 0x00007ffff2f56cc9 in llvm::legacy::PassManager::run (this=this@entry=0x7fffed5c8400, M=...) at /home/aidanhs/Desktop/rust/rust-large/src/llvm/lib/IR/LegacyPassManager.cpp:1734 #15 0x00007ffff203bf4f in LLVMRustWriteOutputFile (Target=0x7fffec217ec0, PMR=0x7fffed5c8400, M=0x7fffed459600, Path=, RustFileType=) at ../rustllvm/PassWrapper.cpp:470 #16 0x00007ffff6dae2e4 in rustc_trans::back::write::write_output_file::h4eabd5e87bd8b06b () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/../lib/librustc_trans-64bf574ec80a57c3.so #17 0x00007ffff6db2fdf in rustc_trans::back::write::optimize_and_codegen::_$u7b$$u7b$closure$u7d$$u7d$::h90577f4377253093 () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/../lib/librustc_trans-64bf574ec80a57c3.so #18 0x00007ffff6db1b70 in rustc_trans::back::write::optimize_and_codegen::h6d075ca45fad08bb () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/../lib/librustc_trans-64bf574ec80a57c3.so #19 0x00007ffff6db57dd in rustc_trans::back::write::execute_work_item::hcc36a5ceda537abc () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/../lib/librustc_trans-64bf574ec80a57c3.so #20 0x00007ffff6db60ae in rustc_trans::back::write::run_work_singlethreaded::h5f9b58b191ca2169 () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/../lib/librustc_trans-64bf574ec80a57c3.so #21 0x00007ffff6db3c71 in rustc_trans::back::write::run_passes::hfdcff321ca143e00 () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/../lib/librustc_trans-64bf574ec80a57c3.so #22 0x00007ffff7aec06b in rustc_driver::driver::phase_5_run_llvm_passes::h32e533cbc3a7bad9 () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-571fa3485abbcd87.so #23 0x00007ffff7ad3b0b in rustc_driver::driver::compile_input::h11cc0ffcaa61b863 () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-571fa3485abbcd87.so #24 0x00007ffff7a7a7a2 in rustc_driver::run_compiler::ha164066ecfb116c6 () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-571fa3485abbcd87.so ---Type to continue, or q to quit--- #25 0x00007ffff7a6ea0c in std::panicking::try::do_call::h48abe9f03a823d2d () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-571fa3485abbcd87.so #26 0x00007ffff77a8c37 in __rust_maybe_catch_panic () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/libstd-f04b25e6ba18446f.so #27 0x00007ffff7a76613 in _$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h8329aa22c9802433 () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-571fa3485abbcd87.so #28 0x00007ffff779e891 in std::sys::imp::thread::Thread::new::thread_start::hfa23ef22483cb516 () from /home/aidanhs/Desktop/rust/rust-large/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/libstd-f04b25e6ba18446f.so #29 0x00007ffff02e56ba in start_thread (arg=0x7fffee7ff700) at pthread_create.c:333 #30 0x00007ffff745482d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109 ```

aidanhs commented 7 years ago

The rust code two comments up (https://github.com/rust-lang/rust/issues/37508#issuecomment-274222951) when compiled with rustc lib.rs --crate-type rlib --emit llvm-bc -C opt-level=1 -C code-model=large will produce lib.bc. Inspecting with llvm-dis:

; ModuleID = 'lib.bc'
source_filename = "lib.cgu-0.rs"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@_ZN3lib3KEY17hf88c4e1e7cc4a068E = internal thread_local global { {}, i1 } zeroinitializer, align 1

; Function Attrs: norecurse nounwind readonly uwtable
define i8* @_ZN3lib3set17hd243fd6d5c29a0c6E() unnamed_addr #0 {
entry-block:
  %0 = load i8, i8* bitcast (i1* getelementptr inbounds ({ {}, i1 }, { {}, i1 }* @_ZN3lib3KEY17hf88c4e1e7cc4a068E, i64 0, i32 1) to i8*), align 1, !range !0
  %1 = icmp eq i8 %0, 0
  %. = select i1 %1, i8* bitcast ({ {}, i1 }* @_ZN3lib3KEY17hf88c4e1e7cc4a068E to i8*), i8* null
  ret i8* %.
}

attributes #0 = { norecurse nounwind readonly uwtable }

!0 = !{i8 0, i8 2}

If you now try and compile this with llc -O1 -code-model=large -relocation-model=pic lib.bc you will hit the assertion (assuming your llvm has assertions enabled):

llc: /home/aidanhs/Desktop/rust/rust-large/src/llvm/include/llvm/CodeGen/MachineOperand.h:411: int64_t llvm::MachineOperand::getImm() const: Assertion `isImm() && "Wrong MachineOperand accessor"' failed.
0  llc             0x00000000019c1060 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 72
1  llc             0x00000000019c13ff
2  llc             0x00000000019bf4a7 llvm::sys::RunSignalHandlers() + 153
3  llc             0x00000000019c08a7
4  libpthread.so.0 0x00007fd3c3b65390
5  libc.so.6       0x00007fd3c2d1b428 gsignal + 56
6  libc.so.6       0x00007fd3c2d1d02a abort + 362
7  libc.so.6       0x00007fd3c2d13bd7
8  libc.so.6       0x00007fd3c2d13c82
9  llc             0x0000000000b8276c
10 llc             0x0000000000d413c6 llvm::X86InstrInfo::convertToThreeAddress(llvm::ilist_iterator<llvm::MachineBasicBlock>&, llvm::MachineInstr&, llvm::LiveVariables*) const + 5096
11 llc             0x000000000138dd05
12 llc             0x0000000001390b48
13 llc             0x0000000001393def
14 llc             0x00000000011ce006 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 426
15 llc             0x0000000001556d7c llvm::FPPassManager::runOnFunction(llvm::Function&) + 330
16 llc             0x0000000001556f15 llvm::FPPassManager::runOnModule(llvm::Module&) + 133
17 llc             0x0000000001557290
18 llc             0x00000000015579a5 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 271
19 llc             0x0000000001557bb1 llvm::legacy::PassManager::run(llvm::Module&) + 39
20 llc             0x0000000000b5948e
21 llc             0x0000000000b57c64 main + 363
22 libc.so.6       0x00007fd3c2d06830 __libc_start_main + 240
23 llc             0x0000000000b55f89 _start + 41
Stack dump:
0.      Program arguments: ../../rust-large/llvm-build/dist/bin/llc -O1 -code-model=large -relocation-model=pic lib.bc 
1.      Running pass 'Function Pass Manager' on module 'lib.bc'.
2.      Running pass 'Two-Address instruction pass' on function '@_ZN3lib3set17hd243fd6d5c29a0c6E'
Aborted (core dumped)

It works fine on the latest LLVM head. Turns out the fix was merged december 7th - https://llvm.org/bugs/show_bug.cgi?id=31271 is the bug, https://reviews.llvm.org/D27481 is the fix.

aidanhs commented 7 years ago

Looking at the llvm 4 release branch on the llvm-mirror github, this will be fixed when rust upgrades - https://github.com/rust-lang/rust/issues/37609.

aidanhs commented 7 years ago

I backported the referenced patch, built a debug rust with it (i.e. debug-rust-large-fixed) and then built a release mode rust also with the backported patch and debug-rust-large-fixed (which took forever) and successfully ended up with a release-rust-large-fixed which can build itself.

Mark-Simulacrum commented 7 years ago

Presumably fixed by LLVM backport -- doesn't reproduce today. I'm marking as E-needstest since it seems like something we should track in tests.

aidanhs commented 7 years ago

@Mark-Simulacrum fwiw this is tricky to do a test for unless we want to do yet another rustc build in CI. I'm going to be rebasing our Rust fork 'shortly' and was planning to just close this issue once that's done and I've verified everything is working.

Mark-Simulacrum commented 7 years ago

Oh... do we need to rebuild rustc for it? I was under the impression that just rustc -Ccode-model=large was enough to test. That's all I did...

aidanhs commented 7 years ago

Urgh yes. Sorry, this issue has a lot of history for me and I'd forgotten parts of it.

Running the #![no_std] testcase above is indeed a valid test of the issue :)

steveklabnik commented 5 years ago

Triage: apparently https://github.com/rust-lang/rust/pull/42724 added a test, but it was removed before it was merged.