[LLVMdev] Bug in Inliner w/ lazy bitcode

Solomon Boulos boulos at cs.stanford.edu
Fri Jul 1 13:00:27 PDT 2011


Hi everyone,

In debugging an LLVM based system with a runtime module loaded from bitcode, I ran into a strange error when trying to use getLazyBitcodeModule instead of just ParseBitcodeFile (when loading lazily I get an "Invalid CALL" during bitcode deserialization). I can't decide if this is a "bug" or just a "you shouldn't use Module/Inliner like this".

The problem is related to using templates (and thereby linkonce_odr) with lazy deserialization. I've reduced it down to a simple test (also attached as bitcode_input.cc):

template<typename T>
class SomeContainer {
public:
   T* getPtr() { return data; }
   T* data;
};

extern "C"
float* RunStuff(void) {
   SomeContainer<float> emptyContainer;
   return emptyContainer.getPtr();
}

This code is compiled via clang into llvm bitcode (clang++ -emit-llvm -c bitcode_input.cc -o test.bc), and then loaded at runtime via getLazyBitcodeModule (see load_bitcode.cc). After "loading" the bitcode, I emit a new function that just calls RunStuff. I then run the Inliner on the full module, and then ask the JIT for getPointerToFunction on my emitted function. At this point, when generating native code, I get an Invalid CALL when it tries to deserialize RunStuff. So the overall process is:

 - Read bitcode from .bc file.
 - Add a new Function to the Module that calls RunStuff.
 - Run the Inliner over the Module.
 - Ask a JIT for getPointerToFunction(emittedFunc)

After digging a bit (verified by dumping the module in load_bitcode.cc before and after inlining), the problem comes from the Inliner removing SomeContainer::getPtr because it believes ("incorrectly") that it's unused (lib/Transforms/IPO/Inliner.cpp:539 in TOT). When the bitcode reader tries to materialize RunStuff, the call to getPtr fails to deserialize properly. It seems to me that removeDeadFunctions should exit early if it runs into _any_ functions that are still materializable as they may contain unseen calls. At the same time, I'm no expert on the linkonce_odr rules, so I'm not sure if this is really a "bug" or just a different design decision.

Steps to reproduce (with LLVM and clang TOT):

clang++ -emit-llvm -c bitcode_input.cc -o test.bc
clang++ `llvm-config --cxxflags --ldflags --libs` load_bitcode.cc
./a.out

Solomon

-------------- next part --------------
A non-text attachment was scrubbed...
Name: load_bitcode.cc
Type: application/octet-stream
Size: 2108 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110701/739e7ba2/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bitcode_input.cc
Type: application/octet-stream
Size: 211 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110701/739e7ba2/attachment-0001.obj>
-------------- next part --------------





More information about the llvm-dev mailing list