[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