[LLVMdev] load bytecode from string for jiting problem (original) (raw)

Willy WOLFF willy.wolff at etu.unistra.fr
Fri Mar 28 02:52:45 PDT 2014


I finally found my problem. For writing the string containing the module to the global variable, I need to have string size + 1 for '\0' at the end of string. But when I want to read for parsing, I forget to remove this last character.

The problem is, the error returning by this test http://llvm.org/docs/doxygen/html/BitcodeReader_8cpp_source.html#l03216 is not handled. I compile llvm with --enable-expensive-checks --enable-debug-runtime --enable-debug-symbols --enable-keep-symbols options. I still have a segfault: (in gdb session) ... bytecode: BC��!

bytecode_length: 4985

Program received signal SIGSEGV, Segmentation fault. llvm::BitstreamCursor::Read (this=0x1a733a0, NumBits=8) at /home/willy/apollo_checks/llvm/include/llvm/ADT/OwningPtr.h:67 67 assert(Ptr && "Cannot dereference null pointer"); (gdb) bt #0 llvm::BitstreamCursor::Read (this=0x1a733a0, NumBits=8) at /home/willy/apollo_checks/llvm/include/llvm/ADT/OwningPtr.h:67 #1 0x0000000000593703 in llvm::BitcodeReader::ParseBitcodeInto (this=0x1a73370, M=0x1a73260) at /home/willy/apollo_checks/llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1976 #2 0x000000000059e620 in llvm::getLazyBitcodeModule (Buffer=0x1a73230, Context=...) at /home/willy/apollo_checks/llvm/lib/Bitcode/Reader/BitcodeReader.cpp:3315 #3 0x000000000059eb26 in llvm::parseBitcodeFile (Buffer=0x8, Context=...) at /home/willy/apollo_checks/llvm/lib/Bitcode/Reader/BitcodeReader.cpp:3347 #4 0x0000000000580e1e in apollo_runtime_hook (id=, info=, skeletons=0x144b9d0, skeleton_size=, params=0x7fffffffdca8, phi_state_size=) at runtime.cpp:264 #5 0x0000000000581886 in bench_loop () at ./src//matrixmul/../include/bench.h:21 #6 kernel (out=, out=, a=..., b=...) at ./src//matrixmul/matrixmul.c:46 #7 main () at ./src//matrixmul/matrixmul.c:65

Did I need to add more configuration option to have error manager do his jobs?

Thanks, Willy

On 03/21/2014 12:04 AM, Vikas Bhargava wrote:

the segfault is not happening because BitStream is NULL, it is happening because BitcodeBytes member variable in BitstreamReader class is NULL. As you can see, getBitcodeBytes de-references BitcodeBytes:

StreamableMemoryObject <http://llvm.org/docs/doxygen/html/classllvm11StreamableMemoryObject.html> &getBitcodeBytes <http://llvm.org/docs/doxygen/html/classllvm11BitstreamReader.html#a55ac0f8d247d2404c59c5e04d2d4e25f>() {return *BitcodeBytes; }

I would still suggest that you put a watchpoint on the underlying memory as it is freed somewhere. thx Vikas. ======= On Thu, Mar 20, 2014 at 3:39 PM, WOLFF Willy (ETU MAI) <willy.wolff at etu.unistra.fr <mailto:willy.wolff at etu.unistra.fr>> wrote: Maybe I found the problem. For debuging, I modify isEndPos of BitstreamReader as follows: original: http://llvm.org/docs/doxygen/html/BitstreamReader8hsource.html#l00234 bool isEndPos(sizet pos) { if (BitStream == NULL) errs() << "BitStream is null\n";_ _else errs() << "BitStream n'est pas null\n";_ _errs() << "isEndPos prob " << pos << " & " << BitStream_ _<<"\n";_ _StreamableMemoryObject& smo =_ _BitStream->getBitcodeBytes(); errs() << "isEndPos prob smo\n";_ _bool m = smo.isObjectEnd(staticcast(pos)); errs() << "isEndPos prob " << m << "\n";_ _return m;_ _}_ _and on my output i never see "isEndPos prob smo\n";_ _The segfault occuring when i call getBitcodeBytes()._ _Also, i don't see the message of "BitStream is null" or "BitStream_ _n'est pas null" ..._ _Is possible that this variable is not correctly initialized?_ _Thanks_ _--_ _Willy WOLFF_ _On Thursday, March 20, 2014 22:32 CET, Vikas Bhargava_ _<vikasbhargava at gmail.com <mailto:vikasbhargava at gmail.com>> wrote: > Hello Willy, > Here is the dump from one of my bitcode files: > > 0000000 42 43 c0 de 21 0c 00 00 25 05 00 00 0b 82 20 00 > > As expected, 0x42 (= B), 0x43 (= C), xc0 and 0xde are in correct order. In > your case, the first byte is read as 37 (= 0x25). I wonder why? When you > check the bytes yourself, you get expected results. When the same bytes are > read from Stream object, you get a different result (maybe garbage). I > would suggest that you put a watchpoint on mbjit->getBufferStart() and > single step your program to make sure it is not freed, over written > somewhere. > > thx > Vikas. > ======= > > > > On Thu, Mar 20, 2014 at 7:50 AM, Willy WOLFF <willy.wolff at etu.unistra.fr <mailto:willy.wolff at etu.unistra.fr>>wrote: > > > The stack trace is: > > (gdb) bt > > #0 0x00000000004fa8c8 in llvm::BitstreamCursor::Read(unsigned int) () > > #1 0x00000000004fa1d2 in llvm::BitcodeReader:: > > ParseBitcodeInto(llvm::Module*) () > > #2 0x0000000000503ae9 in llvm::getLazyBitcodeModule(llvm::MemoryBuffer*, > > llvm::LLVMContext&) () > > #3 0x0000000000503eb6 in llvm::parseBitcodeFile(llvm::MemoryBuffer*, > > llvm::LLVMContext&) () > > #4 0x00000000004ec195 in jitter (skeletons=, > > params=0x7fffffffdf40, phistate=0x11adbc0, lower=0, upper=250, > > instouter=8, instinner=) > > at /home/willy/hellostuff/withapollo/simpleloop/runtime.cpp:263 > > #5 0x00000000004ec8fa in apolloruntimehook (info=, > > skeletons=0xc8b1f0, skeletonsize=, params=0x7fffffffdf40, > > phistatesize=) > > at /home/willy/hellostuff/withapollo/simpleloop/runtime.cpp:438 > > #6 0x00000000004ee753 in ?? () > > #7 0x00000000004ecbf1 in main (argc=, argv= > out>) at /home/willy/hellostuff/withapollo/simpleloop/simple > > scevdynamicarray.c:84 > > > > > > > > > > On 03/20/2014 10:10 AM, Willy WOLFF wrote: > > > >> This segfault occuring only under valgrind, > >> in shell way, and in gdb way i have > >> > >> Invalid bitcode signature > >> simplescevdynamicarray: > >> /home/willy/apollo/llvm/include/llvm/Support/ErrorOr.h:258: storagetype > >> *llvm::ErrorOr<llvm::Module *>::getStorage() [T = llvm::Module *]: > >> Assertion `!HasError && "Cannot get value when an error exists!"' failed. > >> Command terminated by signal 6 > >> > >> > >> this is the code I use: > >> > >> > >> long jitter(void* info, skeletonpair *skeletons, long skeletonsize, > >> paramt params, long phistatesize) { > >> InitializeNativeTarget(); > >> InitializeNativeTargetAsmPrinter(); > >> > >> llvm::StringRef sr (skeletons[idx].jitbytecode, > >> skeletons[idx].jitbytecodelength); > >> > >> if (sr.str()[0] == 'B') > >> std::cout << "B ok\n";_ _> >> if (sr.str()[1] == 'C') > >> std::cout << "C ok\n";_ _> >> if (sr.str()[2] == (char) 0xc0) > >> std::cout << "0xc0 ok\n";_ _> >> if (sr.str()[3] == (char) 0xde) > >> std::cout << "0xde ok\n";_ _> >> llvm::MemoryBuffer* mbjit = llvm::MemoryBuffer::getMemBufferCopy (sr); > >> > >> llvm::ErrorOrllvm::Module* ModuleOrErr = llvm::parseBitcodeFile > >> (mbjit, context); > >> if (llvm::errorcode EC = ModuleOrErr.getError()) { > >> std::cout << ModuleOrErr.getError().message() << "\n";_ _> >> } > >> > >> Module* Mjit = ModuleOrErr.get(); > >> > >> std::string eeError; > >> ExecutionEngine* nee = > >> EngineBuilder(Mjit).setEngineKind(EngineKind::JIT).setUseMCJIT(true). > >> setErrorStr(&eeError).create(); > >> if (!nee) { > >> fprintf(stderr, "Could not create ExecutionEngine: %s\n", > >> eeError.cstr()); > >> assert(false); > >> } > >> > >> Function f = retfct(Mjit); // Function* retfct (Module*); return > >> the function we want to jit. > >> uint64t fptr = nee->getFunctionAddress(f->getName()); > >> > >> long (*fjited)(paramt, phistatet, long, long, long, long) > >> = (long (*)(paramt, phistatet, long, long, long, long)) > >> (intptrt)fptr; > >> > >> returnfjited (params, phistate, lower, upper, instouter, instinner); > >> } > >> > >> > >> Thanks, > >> -- > >> Willy WOLFF > >> > >> > >> On 20 Mar 2014, at 00:37, Vikas Bhargava wrote: > >> > >> segmentation fault indicates memory corruption and it's hard to tell > >>> without seeing the exact use of the APIs. If possible, please post a > >>> complete program and gdb stack trace from the core file. If there are > >>> multiple threads using the global variables, please let us know. > >>> > >>> FWIW, I have some tests to write llvm::Module to bitcode files and > >>> read them back into llvm::Module and they work just fine with 3.4 > >>> (never tried with tip). > >>> > >>> thx > >>> vikas. > >>> ======== > >>> > >>> > >>> On Wed, Mar 19, 2014 at 2:58 PM, Willy WOLFF > >>> <willy.wolff at etu.unistra.fr_ _<mailto:willy.wolff at etu.unistra.fr> <mailto:willy.wolff at etu.unistra.fr_ _<mailto:willy.wolff at etu.unistra.fr>>> wrote: > >>> > >>> all of: > >>> ---- > >>> // cout << "lsr: " << lsr_ _<< "\n";_ _> >>> llvm::MemoryBuffer* mbjit = > >>> > >>> llvm::MemoryBuffer::getMemBufferCopy (sr); > >>> ------ > >>> string lsr = sr.str(); > >>> // cout << "lsr: " << lsr_ _<< "\n";_ _> >>> llvm::MemoryBuffer* mbjit = > >>> > >>> llvm::MemoryBuffer::getMemBuffer (lsr); > >>> ------- > >>> string lsr = sr.str(); > >>> // cout << "lsr: " << lsr_ _<< "\n";_ _> >>> llvm::MemoryBuffer* mbjit = > >>> > >>> llvm::MemoryBuffer::getMemBufferCopy (lsr); > >>> > >>> > >>> have same result as invalid bit code. > >>> The result of valgrind, effectively, i have invalid reads in the > >>> parseBitcodeFile: > >>> > >>> ==536== Conditional jump or move depends on uninitialised value(s) > >>> ==536== at 0x501FE3: llvm::BitstreamCursor::Read(unsigned int) > >>> (in /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x501A19: > >>> llvm::BitcodeReader::ParseBitcodeInto(llvm::Module*) (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x50AEC8: > >>> llvm::getLazyBitcodeModule(llvm::MemoryBuffer*, > >>> llvm::LLVMContext&) (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x50B295: > >>> llvm::parseBitcodeFile(llvm::MemoryBuffer*, llvm::LLVMContext&) > >>> (in /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x4F1231: blahruntimehook (runtime.cpp:348) > >>> ==536== by 0x4F46C2: ??? (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x4F2B60: main (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== > >>> ==536== Invalid read of size 8 > >>> ==536== at 0x501FE8: llvm::BitstreamCursor::Read(unsigned int) > >>> (in /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x501A19: > >>> llvm::BitcodeReader::ParseBitcodeInto(llvm::Module*) (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x50AEC8: > >>> llvm::getLazyBitcodeModule(llvm::MemoryBuffer*, > >>> llvm::LLVMContext&) (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x50B295: > >>> llvm::parseBitcodeFile(llvm::MemoryBuffer*, llvm::LLVMContext&) > >>> (in /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x4F1231: blahruntimehook (runtime.cpp:348) > >>> ==536== by 0x4F46C2: ??? (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x4F2B60: main (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== Address 0x0 is not stack'd, malloc'd or (recently) free'd > >>> ==536== > >>> ==536== > >>> ==536== Process terminating with default action of signal 11 > >>> (SIGSEGV) > >>> ==536== Access not within mapped region at address 0x0 > >>> ==536== at 0x501FE8: llvm::BitstreamCursor::Read(unsigned int) > >>> (in /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x501A19: > >>> llvm::BitcodeReader::ParseBitcodeInto(llvm::Module*) (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x50AEC8: > >>> llvm::getLazyBitcodeModule(llvm::MemoryBuffer*, > >>> llvm::LLVMContext&) (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x50B295: > >>> llvm::parseBitcodeFile(llvm::MemoryBuffer*, llvm::LLVMContext&) > >>> (in /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x4F1231: blahruntimehook (runtime.cpp:348) > >>> ==536== by 0x4F46C2: ??? (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> ==536== by 0x4F2B60: main (in > >>> /home/willy/blahtestscript/newblah/simplescevdynamicarray) > >>> > >>> > >>> > >>> -- > >>> Willy WOLFF > >>> > >>> > >>> On 19 Mar 2014, at 22:11, Vikas Bhargava wrote: > >>> > >>> Hi Willy, > >>>> If the disassembly of the module works fine, then there is > >>>> nothing wrong with the module. > >>>> > >>>> Stream uses the memorybuffer that you pass in parseBitcodeFile. > >>>> If what Will is saying is true, there is something wrong with > >>>> your code in "3:", i.e.: > >>>> > >>>> MemoryBuffer* mbjit = MemoryBuffer::getMemBuffer (sr.str()); > >>>> LLVMContext& context = getGlobalContext(); > >>>> ErrorOr<Module*> ModuleOrErr = parseBitcodeFile (mbjit, context); > >>>> if (errorcode EC = ModuleOrErr.getError()) > >>>> { > >>>> std::cout << ModuleOrErr.getError()._ _> >>>> message() << "\n";_ _> >>>> assert(false); > >>>> } > >>>> > >>>> Can you post how you modified it in your second reply? For > >>>> debugging purpose, you can simply use > >>>> MemoryBuffer::getMemBufferCopy() and not worry about validity of > >>>> stringref or null-termination. Also, you can run your program > >>>> through valgrind and check for any invalid reads. > >>>> > >>>> HTH > >>>> Vikas. > >>>> ======= > >>>> > >>>> > >>>> > >>>> On Wed, Mar 19, 2014 at 10:32 AM, Willy WOLFF > >>>> <willy.wolff at etu.unistra.fr_ _<mailto:willy.wolff at etu.unistra.fr> <mailto:willy.wolff at etu.unistra.fr <mailto:willy.wolff at etu.unistra.fr>>> > >>>> > >>>> wrote: > >>>> > >>>> I mad the change, and still have the problem. > >>>> > >>>> I investigate more the source code of llvm. > >>>> > >>>> First, I change isRawBitcode function to print the content of > >>>> the parameter like this: > >>>> original: > >>>> http://llvm.org/docs/doxygen/_html/ReaderWriter8hsource. > >>>> html#l00081 > >>>> > >>>> <http://llvm.org/docs/doxygen/html/ReaderWriter8hsource._ _> >>>> html#l00081> > >>>> > >>>> inline bool isRawBitcode(const unsigned char *BufPtr, > >>>> const unsigned char *BufEnd) { > >>>> // These bytes sort of have a hidden message, but it's not > >>>> in > >>>> // little-endian this time, and it's a little redundant. > >>>> errs()<< "isRawBitcode output:\n";_ _> >>>> for (int i = 0; i < 4; i++)_ _> >>>> errs() << BufPtr[i] << "\n";_ _> >>>> if (BufPtr != BufEnd ) > >>>> errs() << "BP != BE ok\n";_ _> >>>> if (BufPtr[0] == 'B') > >>>> errs() << "B ok\n";_ _> >>>> if (BufPtr[1] == 'C') > >>>> errs() << "C ok\n";_ _> >>>> if (BufPtr[2] == 0xc0) > >>>> errs() << "0xc0 ok\n";_ _> >>>> if (BufPtr[3] == 0xde) > >>>> errs() << "0xde ok\n";_ _> >>>> > >>>> return BufPtr != BufEnd && > >>>> BufPtr[0] == 'B' && > >>>> BufPtr[1] == 'C' && > >>>> BufPtr[2] == 0xc0 && > >>>> BufPtr[3] == 0xde; > >>>> } > >>>> > >>>> > >>>> Second, I change ParseBitcodeInto as this: > >>>> original: > >>>> http://llvm.org/docs/doxygen/html/BitcodeReader8cpp > >>>> source.html#l01971 > >>>> > >>>> <http://llvm.org/docs/doxygen/html/BitcodeReader8cpp_ _> >>>> source.html#l01971> > >>>> ... > >>>> errs() << "parsebitcodeinto sniff the_ _signature\n";_ _> >>>> uint32t bvar = Stream.Read(8); > >>>> errs() << "B :" << bvar << "\n";_ _> >>>> if (bvar != 'B') { > >>>> errs() << "B :" << bvar << "\n";_ _> >>>> return Error(InvalidBitcodeSignature);_ > >>>> > >>>> } > >>>> > >>>> if (Stream.Read(8) != 'C') { > >>>> errs() << "C\n";_ _> >>>> return Error(InvalidBitcodeSignature);_ > >>>> > >>>> } > >>>> if ( Stream.Read(8) != 0xc0 ) { > >>>> errs() << "0xc0\n";_ _> >>>> return Error(InvalidBitcodeSignature);_ > >>>> > >>>> } > >>>> if ( Stream.Read(8) != 0xde ) { > >>>> errs() << "0xde\n";_ _> >>>> return Error(InvalidBitcodeSignature);_ > >>>> > >>>> } > >>>> // if (Stream.Read(8) != 'B' || > >>>> // Stream.Read(8) != 'C' || > >>>> // Stream.Read(4) != 0x0 || > >>>> // Stream.Read(4) != 0xC || > >>>> // Stream.Read(4) != 0xE || > >>>> // Stream.Read(4) != 0xD > >>>> // ) { > >>>> ... > >>>> > >>>> > >>>> > >>>> The output of the code is : > >>>> > >>>> > >>>> isRawBitcode output: > >>>> B > >>>> C > >>>> > >>>> > >>>> BP != BE ok > >>>> > >>>> B ok > >>>> C ok > >>>> 0xc0 ok > >>>> 0xde ok > >>>> > >>>> parsebitcodeinto sniff the signature > >>>> B :37 > >>>> B :37 > >>>> > >>>> > >>>> > >>>> > >>>> It's possible that Stream object is not correctly initialized? > >>>> > >>>> > >>>> On 03/13/2014 06:37 PM, Will Dietz wrote: > >>>> > >>>> On Thu, Mar 13, 2014 at 9:02 AM, Willy WOLFF > >>>> <willy.wolff at etu.unistra.fr_ _<mailto:willy.wolff at etu.unistra.fr> > >>>> <mailto:willy.wolff at etu.unistra.fr_ _<mailto:willy.wolff at etu.unistra.fr>>> wrote: > >>>> > >>>> Hello, > >>>> > >>>> I having a weird problem while writing a bytecode > >>>> module to a string, > >>>> and after read/parse it for unsing on a jit. > >>>> > >>>> I write a pass to export function to module, and put > >>>> this module inside > >>>> a global variable. > >>>> I use WriteBitcodeToFile for this. > >>>> For debuging, after this write, I try to load the > >>>> exported module with > >>>> parseBitcodeFile. > >>>> This two step works. > >>>> > >>>> > >>>> > >>>> After, while the compiled program is running, I try > >>>> to read and parse > >>>> this global variable for jiting the function. > >>>> > >>>> 1) I read the global variable with > >>>> StringRef sr (gv, gvlength); > >>>> > >>>> 2) I manually test this bytecode by > >>>> (inspired by inline bool isRawBitcode(const unsigned > >>>> char *BufPtr, > >>>> const unsigned char *BufEnd) at > >>>> http://llvm.org/docs/doxygen/ _> >>>> html/ReaderWriter8hsource.html#l00067 > >>>> <http://llvm.org/docs/doxygen/_ _> >>>> html/ReaderWriter8hsource.html#l00067>) > >>>> > >>>> if (sr.str()[0] == 'B') > >>>> std::cout << "B ok\n";_ _> >>>> if (sr.str()[1] == 'C') > >>>> std::cout << "C ok\n";_ _> >>>> if (sr.str()[2] == (char) 0xc0) > >>>> std::cout << "0xc0 ok\n";_ _> >>>> if (sr.str()[3] == (char) 0xde) > >>>> std::cout << "0xde ok\n";_ _> >>>> > >>>> 3) I try to parse the gv by > >>>> MemoryBuffer* mbjit = MemoryBuffer::getMemBuffer > >>>> (sr.str()); > >>>> > >>>> > >>>> Not sure if this is your issue, but should be fixed anyway: > >>>> > >>>> The std::string created by "sr.str()" ends its lifetime > >>>> in this > >>>> statement, and MemoryBuffer for efficiency reasons > >>>> avoids copying data it doesn't have to (like StringRef) > >>>> so will be > >>>> referencing the freed memory. > >>>> > >>>> To resolve this: > >>>> * Pass MemoryBuffer your StringRef directly > >>>> * Use getMemBufferCopy() > >>>> * Preserve the result of sr.str() into a stack variable > >>>> and pass that > >>>> to getMemoryBuffer() instead. > >>>> > >>>> As a final note, check if your bitcode buffer "string" is > >>>> null-terminated or not. If not, be sure to be careful and > >>>> do things like informing MemoryBuffer that this is the case. > >>>> > >>>> Hope this helps, > >>>> ~Will > >>>> > >>>> LLVMContext& context = getGlobalContext(); > >>>> ErrorOr<Module*> ModuleOrErr = parseBitcodeFile > >>>> (mbjit, context); > >>>> if (errorcode EC = ModuleOrErr.getError()) > >>>> { > >>>> std::cout <<_ _ModuleOrErr.getError()._message()_ _> >>>> > >>>> << "\n";_ _> >>>> assert(false); > >>>> } > >>>> > >>>> > >>>> > >>>> > >>>> This is the execution result: > >>>> B ok > >>>> C ok > >>>> 0xc0 ok > >>>> 0xde ok > >>>> Invalid bitcode signature > >>>> > >>>> > >>>> > >>>> Ok is not working :/ > >>>> But why ??? > >>>> > >>>> > >>>> > >>>> For debuging, between 2) and 3), I export the readed > >>>> module and write to > >>>> a file on my hard drive, > >>>> and try llvm-dis, and the dissasembly of the module > >>>> works. > >>>> > >>>> Wath's wrong? Any idea for solve this problem? > >>>> > >>>> Thanks you very much. > >>>> > >>>> Regards, > >>>> Willy > >>>>


> >>>> LLVM Developers mailing list > >>>> LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu> <mailto:LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>> > >>>> http://llvm.cs.uiuc.edu <http://llvm.cs.uiuc.edu/> > >>>> http://lists.cs.uiuc.edu/_mailman/listinfo/llvmdev > >>>> <http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev> > >>>> _> >>>> _________________________ > >>>> LLVM Developers mailing list > >>>> LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu> <mailto:LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>> > >>>> http://llvm.cs.uiuc.edu <http://llvm.cs.uiuc.edu/> > >>>> http://lists.cs.uiuc.edu/_mailman/listinfo/llvmdev > >>>> <http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev> > >>>> > >>>> > >>>> > >>> > >>> > >> > >> _> >> ________________________ > >> LLVM Developers mailing list > >> LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu> http://llvm.cs.uiuc.edu > >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >> > >>



More information about the llvm-dev mailing list