Julia: recent crashes inside llvm-alloc-opt

Created on 23 Sep 2017  Â·  2Comments  Â·  Source: JuliaLang/julia

Seen in CI builds:

https://travis-ci.org/JuliaLang/julia/jobs/278782914 :
https://travis-ci.org/JuliaLang/julia/jobs/278783094 :

julia: /home/travis/build/JuliaLang/julia/usr/include/llvm/IR/Instructions.h:866: static llvm::GetElementPtrInst* llvm::GetElementPtrInst::Create(llvm::Type*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, const llvm::Twine&, llvm::Instruction*): Assertion `PointeeType == cast<PointerType>(Ptr->getType()->getScalarType())->getElementType()' failed.
signal (6): Aborted
in expression starting at no file:0
__kernel_vsyscall at  (unknown line)
gsignal at /lib/i386-linux-gnu/libc.so.6 (unknown line)
abort at /lib/i386-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x559bc7c6)
__assert_fail at /lib/i386-linux-gnu/libc.so.6 (unknown line)
Create at /home/travis/build/JuliaLang/julia/usr/include/llvm/IR/Instructions.h:864
Create at /home/travis/build/JuliaLang/julia/usr/include/llvm/IR/Instructions.h:1064 [inlined]
operator() at /home/travis/build/JuliaLang/julia/src/llvm-alloc-opt.cpp:587 [inlined]
replaceUsesWith at /home/travis/build/JuliaLang/julia/src/llvm-alloc-opt.cpp:599
runOnFunction at /home/travis/build/JuliaLang/julia/src/llvm-alloc-opt.cpp:709

https://travis-ci.org/JuliaLang/julia/jobs/278786438 :

_ZN4llvm23ReplaceableMetadataImpl11getIfExistsERNS_8MetadataE at /home/travis/build/JuliaLang/julia/usr/bin/../lib/libLLVM-3.9.so (unknown line)
_ZN4llvm16MetadataTracking7untrackEPvRNS_8MetadataE at /home/travis/build/JuliaLang/julia/usr/bin/../lib/libLLVM-3.9.so (unknown line)
untrack at /home/travis/build/JuliaLang/julia/usr/include/llvm/IR/Metadata.h:219 [inlined]
untrack at /home/travis/build/JuliaLang/julia/usr/include/llvm/IR/TrackingMDRef.h:85 [inlined]
operator= at /home/travis/build/JuliaLang/julia/usr/include/llvm/IR/TrackingMDRef.h:37 [inlined]
operator= at /home/travis/build/JuliaLang/julia/usr/include/llvm/IR/TrackingMDRef.h:110 [inlined]
operator= at /home/travis/build/JuliaLang/julia/usr/include/llvm/IR/DebugLoc.h:42 [inlined]
setDebugLoc at /home/travis/build/JuliaLang/julia/usr/include/llvm/IR/Instruction.h:231 [inlined]
operator() at /home/travis/build/JuliaLang/julia/src/llvm-alloc-opt.cpp:578 [inlined]
replaceUsesWith at /home/travis/build/JuliaLang/julia/src/llvm-alloc-opt.cpp:599
runOnFunction at /home/travis/build/JuliaLang/julia/src/llvm-alloc-opt.cpp:709
_ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE at /home/travis/build/JuliaLang/julia/usr/bin/../lib/libLLVM-3.9.so (unknown line)
_ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE at /home/travis/build/JuliaLang/julia/usr/bin/../lib/libLLVM-3.9.so (unknown line)
_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE at /home/travis/build/JuliaLang/julia/usr/bin/../lib/libLLVM-3.9.so (unknown line)
_ZN4llvm6legacy11PassManager3runERNS_6ModuleE at /home/travis/build/JuliaLang/julia/usr/bin/../lib/libLLVM-3.9.so (unknown line)
jl_dump_native at /home/travis/build/JuliaLang/julia/src/jitlayers.cpp:1220
upstream

Most helpful comment

AFAICT this is a GCC 4.8 bug.

I managed to reproduce this by running almost exactly the same code in almost exactly the same travis x86 environment and played it back and forth for a few hours in rr.... This is only reproducible with at least -O2 when compiling julia C++ code and only on 4.8 (at least not on gcc7, I'm confused what circuclar is using since 4.8 is requested but the installation log also shows gcc-4.9-multilib will be installed...) Adding unrelated debug printing function calls can also make the issue go away.

The particular failure I reproduce is cased by the line replace_i = new BitCastInst(replace_i, cast_t, "", user);. This is compiled to

   0x2a445577 <+4911>:  call   0x2a3327c0 <llvm::User::operator new(unsigned int, unsigned int)@plt>
   0x2a44557c <+4916>:  mov    %eax,-0x16c(%ebp)
   0x2a445582 <+4922>:  mov    -0x15c(%ebp),%edx
   0x2a445588 <+4928>:  mov    %edx,0x10(%esp)
   0x2a44558c <+4932>:  lea    -0x104(%ebp),%esi
   0x2a445592 <+4938>:  mov    %esi,0xc(%esp)
   0x2a445596 <+4942>:  mov    -0x160(%ebp),%ecx
   0x2a44559c <+4948>:  mov    %ecx,0x8(%esp)
   0x2a4455a0 <+4952>:  mov    %edi,0x4(%esp)
   0x2a4455a4 <+4956>:  mov    %edi,(%esp)
   0x2a4455a7 <+4959>:  call   0x2a333960 <llvm::BitCastInst::BitCastInst(llvm::Value*, llvm::Type*, llvm::Twine const&, llvm::Instruction*)@plt>

Note that the new operator call at <+4911> returns the allocated memory in $eax and then it's not used in the constructor call. Additionally, line <+4948> to <+4956> sets up the this pointer and first two arguments for the call and it uses the same value for this and the first argument!!!! From within the debugger, both turns out to be the old replace_i. It basically seems that the compiler emits the code for

operator new(...);
new (replace_i) BitCastInst(replace_i, cast_t, "", user);

instead, which makes the new replace_i to be %5 = bitcast i8* %5 to i8* and then causes all sort of cascading effect downstream. Can we upgrade the compiler on travis? I thought we were using gcc 5 at some point.

All 2 comments

AFAICT this is a GCC 4.8 bug.

I managed to reproduce this by running almost exactly the same code in almost exactly the same travis x86 environment and played it back and forth for a few hours in rr.... This is only reproducible with at least -O2 when compiling julia C++ code and only on 4.8 (at least not on gcc7, I'm confused what circuclar is using since 4.8 is requested but the installation log also shows gcc-4.9-multilib will be installed...) Adding unrelated debug printing function calls can also make the issue go away.

The particular failure I reproduce is cased by the line replace_i = new BitCastInst(replace_i, cast_t, "", user);. This is compiled to

   0x2a445577 <+4911>:  call   0x2a3327c0 <llvm::User::operator new(unsigned int, unsigned int)@plt>
   0x2a44557c <+4916>:  mov    %eax,-0x16c(%ebp)
   0x2a445582 <+4922>:  mov    -0x15c(%ebp),%edx
   0x2a445588 <+4928>:  mov    %edx,0x10(%esp)
   0x2a44558c <+4932>:  lea    -0x104(%ebp),%esi
   0x2a445592 <+4938>:  mov    %esi,0xc(%esp)
   0x2a445596 <+4942>:  mov    -0x160(%ebp),%ecx
   0x2a44559c <+4948>:  mov    %ecx,0x8(%esp)
   0x2a4455a0 <+4952>:  mov    %edi,0x4(%esp)
   0x2a4455a4 <+4956>:  mov    %edi,(%esp)
   0x2a4455a7 <+4959>:  call   0x2a333960 <llvm::BitCastInst::BitCastInst(llvm::Value*, llvm::Type*, llvm::Twine const&, llvm::Instruction*)@plt>

Note that the new operator call at <+4911> returns the allocated memory in $eax and then it's not used in the constructor call. Additionally, line <+4948> to <+4956> sets up the this pointer and first two arguments for the call and it uses the same value for this and the first argument!!!! From within the debugger, both turns out to be the old replace_i. It basically seems that the compiler emits the code for

operator new(...);
new (replace_i) BitCastInst(replace_i, cast_t, "", user);

instead, which makes the new replace_i to be %5 = bitcast i8* %5 to i8* and then causes all sort of cascading effect downstream. Can we upgrade the compiler on travis? I thought we were using gcc 5 at some point.

Damn, that's some find debugging.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

StefanKarpinski picture StefanKarpinski  Â·  3Comments

sbromberger picture sbromberger  Â·  3Comments

StefanKarpinski picture StefanKarpinski  Â·  3Comments

omus picture omus  Â·  3Comments

musm picture musm  Â·  3Comments