llvm-dis fails to parse bytecode emitted by clang

Hi,

I am trying to generate LLVM bytecode using CLANG and I ran into the
following problem. If I run clang with the -emit-llvm option and then
try to get a textual representation of the output using llvm-dis, the
latter crashes because of a failed assertion in BitCodeReader.cpp,
mentioning a "Type mismatch in value table" (the exact error message
is appended at the end of this email). However, if I generate the
bytecode from the same source using llvm-gcc instead of clang,
llvm-dis works fine.

I am also experiencing another (potentially unrelated problem). If I
try to run clang without the "-c" option (i.e. to generate an
executable instead of an object file) it crashes emitting the message
" clang: error: 'x86_64-unknown-linux-gnu': unable to pass LLVM
bit-code files to linker". Output for this problem is also attached.

Could anyone shed some light on those problem? I am using CLANG/LLVM
2.8 compiled from source. The test program I am trying to compile is
simply:

int main()
{
  return 0;
}

Thanks,
Lorenzo De Carli

Output for problem #1:
$ clang -c -emit-llvm test.c -o test.bc
$ llvm-dis test.bc
llvm-dis: BitcodeReader.cpp:205: llvm::Value*
llvm::BitcodeReaderValueList::getValueFwdRef(unsigned int, const
llvm::Type*): Assertion `(Ty == 0 || Ty == V->getType()) && "Type
mismatch in value table!"' failed.
0 llvm-dis 0x00000000006131c6
1 llvm-dis 0x0000000000613502
2 libc.so.6 0x00000039cf4302d0
3 libc.so.6 0x00000039cf430265 gsignal + 53
4 libc.so.6 0x00000039cf431d10 abort + 272
5 libc.so.6 0x00000039cf4296e6 __assert_fail + 246
6 llvm-dis 0x000000000051005b
llvm::BitcodeReaderValueList::getValueFwdRef(unsigned int, llvm::Type
const*) + 173
7 llvm-dis 0x000000000052e574
llvm::BitcodeReader::getFnValueByID(unsigned int, llvm::Type const*) +
42
8 llvm-dis 0x000000000051482b
llvm::BitcodeReader::ParseFunctionBody(llvm::Function*) + 11371
9 llvm-dis 0x000000000051574a
llvm::BitcodeReader::materializeFunction(llvm::Function*,
std::string*) + 284
10 llvm-dis 0x000000000050ddca
llvm::BitcodeReader::materializeModule(std::string*) + 210
11 llvm-dis 0x00000000005171b2
llvm::ParseBitcodeFile(llvm::MemoryBuffer*, std::string*) + 74
12 llvm-dis 0x000000000050b894 main + 160
13 libc.so.6 0x00000039cf41d994 __libc_start_main + 244
14 llvm-dis 0x000000000050b569 __gxx_personality_v0 + 625
Aborted

Output for problem #2:
$ clang -emit-llvm -c test.c [WORKS FINE]
$ clang -emit-llvm test.c
clang: error: 'x86_64-unknown-linux-gnu': unable to pass LLVM bit-code
files to linker

Hi Lorenzo,

I am trying to generate LLVM bytecode using CLANG and I ran into the
following problem. If I run clang with the -emit-llvm option and then
try to get a textual representation of the output using llvm-dis, the
latter crashes because of a failed assertion in BitCodeReader.cpp,
mentioning a "Type mismatch in value table" (the exact error message
is appended at the end of this email). However, if I generate the
bytecode from the same source using llvm-gcc instead of clang,
llvm-dis works fine.

I've seen similar errors to this in the past, and they invariably meant that
LLVM and/or clang had been miscompiled by the system compiler. Take a look at
http://llvm.org/docs/GettingStarted.html#brokengcc

Ciao,

Duncan.

Hi,

For the first problem, try
clang -S -emit-llvm test.c -o test.ll
you should get the llvm IR and you don't need to use llvm-dis. Although I
have tried your example with the exact commands and source code you posted
and it worked just fine for me. I also use clang and LLVM 2.8 compiled from
sources.

For the second problem, suppress -emit-llvm, since you want the executable,
not an object file:
clang test.c -o test.

Hope this helps,
Alexandra

Lorenzo De Carli-3 wrote:

Hi,

how can i correctly calculate the size of a member of a struct (including alignment etc)?
This doesn't work :

         const StructType *STy = cast<StructType>(Ty);
         for (StructType::element_iterator I = STy->element_begin(),
                E = STy->element_end(); I != E; ++I)
         {
             usigned size =I->get()->getScalarSizeInBits(); //often returns 0, not what I need
         }

Basically I want to add up the sizes of the different members to calculate the offset (which I want to compare to
DIType::getOffsetInBits()). Or if there is a direct way to get the offset of a struct member without adding their sizes that'd be even better.

Thx,
Alex

Hi Alex,

I think you are looking for getStructLayout from TargetData (the
StructLayout type is also defined in TargetData.h).

Ciao,

Duncan.

Thanks to everyone for the quick replies! I spent some time looking
into the issue. It turns out that llvm-dis crashes on CLANG-generated
bytecode if LLVM is compiled for a 64-bit architecture. The problem
disappears when compiling for a 32-bit architecture. Should I file a
bug report?

Lorenzo

Thanks to everyone for the quick replies! I spent some time looking
into the issue. It turns out that llvm-dis crashes on CLANG-generated
bytecode if LLVM is compiled for a 64-bit architecture. The problem
disappears when compiling for a 32-bit architecture. Should I file a
bug report?

Thanks,
Lorenzo

Hi Lorenzo,

Thanks to everyone for the quick replies! I spent some time looking
into the issue. It turns out that llvm-dis crashes on CLANG-generated
bytecode if LLVM is compiled for a 64-bit architecture. The problem
disappears when compiling for a 32-bit architecture. Should I file a
bug report?

it still sounds like LLVM is being miscompiled to me. What compiler
did you use to build LLVM?

Ciao,

Duncan.

Ehm... this is embarassing. I realized that an old version of LLVM was
laying around on my machine and in $PATH, so I was running an old
version of llvm-dis without realizing it. Once I removed it,
everything started working perfectly.

Sorry for the false alarm :frowning:

Lorenzo

You can also use getelementptr to get the offset of a struct member:

http://nondot.org/sabre/LLVMNotes/SizeOf-OffsetOf-VariableSizedStructs.txt

Yup, except that this returns a constant expression in general, rather than
a number. There's even a helper for doing this: ConstantExpr:getOffsetOf

Ciao,

Duncan.