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

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

Closed
aidanhs opened this issue Nov 1, 2016 · 12 comments · Fixed by #86352
Closed

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

aidanhs opened this issue Nov 1, 2016 · 12 comments · Fixed by #86352
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.

Comments

@aidanhs
Copy link
Member

aidanhs commented Nov 1, 2016

(allowing specifying code models was added to rustc in #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
Copy link
Member Author

aidanhs commented Nov 1, 2016

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
Copy link
Member Author

aidanhs commented Nov 3, 2016

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
Copy link
Member Author

aidanhs commented Jan 21, 2017

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
Copy link
Member Author

aidanhs commented Jan 21, 2017

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=<optimised out>, 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=<optimised out>)
    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=<optimised out>, 
    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=<optimised out>, 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=<optimised out>)
    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=<optimised out>, RustFileType=<optimised out>)
    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 <return> to continue, or q <return> 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 aidanhs changed the title Unable to compile rustc with RUSTFLAGS="-C code-model=large" Error with -C code-model=large and thread locals Jan 21, 2017
@aidanhs
Copy link
Member Author

aidanhs commented Jan 24, 2017

The rust code two comments up (#37508 (comment)) 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
Copy link
Member Author

aidanhs commented Jan 24, 2017

Looking at the llvm 4 release branch on the llvm-mirror github, this will be fixed when rust upgrades - #37609.

aidanhs added a commit to hadeaninc/llvm-hadean that referenced this issue Feb 14, 2017
aidanhs added a commit to hadeaninc/llvm-hadean that referenced this issue Feb 14, 2017
@aidanhs
Copy link
Member Author

aidanhs commented Feb 16, 2017

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
Copy link
Member

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.

@Mark-Simulacrum Mark-Simulacrum added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. labels May 23, 2017
@aidanhs
Copy link
Member Author

aidanhs commented May 23, 2017

@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
Copy link
Member

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
Copy link
Member Author

aidanhs commented May 23, 2017

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 :)

Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue Jun 22, 2017
Add tests for a few issues.

Fixes rust-lang#41998
Fixes rust-lang#38381
Fixes rust-lang#37515
Fixes rust-lang#37510
Fixes rust-lang#37508
Fixes rust-lang#37366
Fixes rust-lang#37323
Fixes rust-lang#37051
Fixes rust-lang#36839
Fixes rust-lang#35570
Fixes rust-lang#34373
Fixes rust-lang#34222

Certainly not all of the E-needstest issues right now, but I started to get bored.
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 26, 2017
@steveklabnik
Copy link
Member

Triage: apparently #42724 added a test, but it was removed before it was merged.

m-ou-se pushed a commit to m-ou-se/rust that referenced this issue Apr 28, 2021
m-ou-se added a commit to m-ou-se/rust that referenced this issue Apr 28, 2021
…-37508, r=Mark-Simulacrum

Add test for thread-local and code-model=large

Closes rust-lang#37508
jackh726 added a commit to jackh726/rust that referenced this issue Apr 29, 2021
…-37508, r=Mark-Simulacrum

Add test for thread-local and code-model=large

Closes rust-lang#37508
yerke added a commit to yerke/rust that referenced this issue Jun 17, 2021
fee1-dead added a commit to fee1-dead-contrib/rust that referenced this issue Jun 22, 2021
…ark-Simulacrum

Add regression test for issue rust-lang#37508

Add regression test for issue rust-lang#37508

Closes rust-lang#37508

Took this test from rust-lang#37508 and updated the panic handler to the modern standard.

r? `@Mark-Simulacrum`

Mark, I hope you don't me tagging you here. You were involved in the original issue and I hope you might be more comfortable reviewing this.
@bors bors closed this as completed in c38111c Jun 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.
Projects
None yet
3 participants