[LLVMdev] PointerIntPair causing trouble
Stefanus Du Toit
stefanus.dutoit at rapidmind.com
Sun May 3 09:56:47 PDT 2009
On 1-May-09, at 8:35 PM, Chris Lattner wrote:
> I still don't understand why this is a problem, but I decreased the
> default to 2 bits. Please verify that this helps,
I think I've figured out what's going on, and why no assertions are
caused by this. It doesn't necessarily have anything to do with User*
pointer alignment per se (although I believe that could still cause
trouble, though I would expect asserts to catch things in that case).
Here's what I think is happening:
Use::getUser() casts the last element of the Use array to an
AugmentedUse, then pulls out the tagged pointer that AugmentedUse adds.
However, in the case where the User is actually located at the end of
the Use array, there's no tagged pointer there, just some "random"
data corresponding to the first sizeof(User*) bits of a User instance.
The code seems to assume that the relevant bit from the tagged pointer
in AugmentedUse is going to be zero in that case -- if that bit is
one, it considers the AugmentedUse reference valid and pulls out the
pointer.
Since Value (and therefore User) is polymorphic, there's (probably?)
going to be a vtable pointer at the beginning of User. So this code
seems to be assuming that the relevant bit of that vtable pointer is
going to be zero. I'm guessing that virtual tables from MSVC happen to
be less strictly aligned than those from GCC/Linux/OS X.
Now I'm wondering what to do about this. If we know that the first
sizeof(User*) bits of User are indeed always a virtual table pointer,
and that the vtables are aligned to at least 4 bytes, then the current
solution (setting the alignment of User* to 4 bytes) will continue
work. There's the question of whether we really want to rely on this
though.
If we don't want to rely on this, we need to distinguish between
indirectly referred Users and at-end-of-Use-array Users differently
somehow. Of course we could just always store a User* and set it to
null if the User is at the end of the array, but that would increase
the size of most Users by sizeof(User*). Maybe we could encode this
information somehow into the tag bits of the Uses, but I can't see an
easy way to do this.
I'd appreciate your thoughts. In the meantime I will probably commit
some additional comments for Use.cpp to make the code a bit easier to
understand, as well as putting an assert in place to catch this earlier.
Stefanus
--
Stefanus Du Toit <stefanus.dutoit at rapidmind.com>
RapidMind Inc.
phone: +1 519 885 5455 x116 -- fax: +1 519 885 1463
More information about the llvm-dev
mailing list