Bugzilla – Bug 330
Linker causes erroneous asssertion
Last modified: 2004-05-06 17:19:52
You need to log in before you can comment on or make changes to this bug.
When linking these two bytecode files together, llvm-link produces this erroneous assertion: llvm-link: /home/vadve/criswell/llvm/lib/VMCore/Constants.cpp:1212: static llvm::Constant* llvm::ConstantExpr::getGetElementPtrTy(const llvm::Type*, llvm::Constant*, const std::vector<llvm::Constant*, std::allocator<llvm::Constant*> >&): Assertion `GetElementPtrInst::getIndexedType(C->getType(), std::vector<Value*>(IdxList.begin(), IdxList.end()), true) && "GEP indices invalid!"' failed. Removing the %current definition causes the files to link. These input files are reduced from n_tty.c and tty_io.c from the Linux kernel.
Created an attachment (id=109) [details] First input file to link
Created an attachment (id=110) [details] Second input file to link These files should be assembled and then linked as follows: llvm-link -f -o me file1.bc file2.bc The order may be important.
Thanks John! I'll take a look when I get a chance, but it may not be for a couple of days. If you'd like to dig into it, feel free. :) -Chris
I have been (and still am) digging into this, but please feel free to help. :)
After doing some digging, I have found that the test case performs type resolution incorrectly. In line 315 of llvm/lib/VMCore/SymbolTable.cpp, the void function with the getelementptr instruction has the instruction changed from this: volatile store void (%struct.tty_struct*)* %tty_default_put_char, void (%struct.tty_struct*)** getelementptr (%struct.tty_driver* %.dev_tty_driver_394, uint 0, uint 1) to this: volatile store void (%struct.tty_struct*)* %tty_default_put_char, void (%struct.tty_struct*)** getelementptr (opaque %.dev_tty_driver_394, uint 0, uint 1) Since the argument to the getelementptr instruction becomes opaque, the argument to it are no longer valid. I do not know yet why this is happening. It fails to happen when the global values are removed, but will continue to happen as long as %current in the first input file is a pointer to a derived type that isn't used anywhere else in the first LLVM assembly file.
FYI, I believe that this bug is not a memory corruption bug. Comparing a successful link to an asserting link, I've discovered that the difference is in the order in which two abstract type users are refined. In a successful link, a type's abstract type users are: { { opaque92 } } { opaque92 } * whereas for an unsuccessful link, the type users are: { opaque98 } * { { opaque98 } } If the struct pointer is resolved first, the link works. If the embedded structure is resolved first, the link fails on the getelementptr() assertion as described in Comments #1 and #5. This sort of explains why removing %current allows the link to succeed. It also indicates that this is probably a logic bug, since the type resolutions are more or less the same up to this point in execution.
Created an attachment (id=111) [details] First input file to link This is a newer version of the file that is (hopefully) smaller and more straight-forward.
Created an attachment (id=112) [details] Second input file to link This is a (hopefully) smaller and more straight forward version of the original second input file.
This is fixed by: http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20040503/014146.html This change only fixes the given test case. There may be other problems lurking in the dark. I have tried changing PATypeHandle to foward to new types (which should fix all possible cases of this bug), but that breaks the bytecode reader. Since I've already lost some time on this one, and since the bug does not appear often, I am closing this bug and will open a low priority one for the general case. When the general case is fixed (or we discover that there is no general case), we'll close the new bug.
Switched bug to being in VMCore because it is really a type resolution bug.