[LLVMdev] PointerIntPair causing trouble

Gabor Greif ggreif at gmail.com
Sun May 3 13:57:15 PDT 2009


On 3 Mai, 18:56, Stefanus Du Toit <stefanus.dut... at rapidmind.com>
wrote:
> 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.

Hi Stefanus!

Your analysis is perfectly correct. I Was AFK for the last two days,
so I couldn't
tell you this same story.

The algorithm relies on the fact that the LSBit of the first "pointer"
in User
is zero. This is normally the case with VPtrs, which are "normally"
placed there
by ABIs. Originally, I just checked that bit verbatim, and later by
means of
PointerIntPair. The problem arose when PointerIntPair's layout
changed.
I think we could switch back without a loss.

Btw. the alignment of pointers in a 32 bit machine is 4, so I do not
understand
how the traits define 3 free bits for them. Maybe sabre can explain
that change
which caused the breakage.

Is there any acute breakage left?

I assume that there will be problems with layouts on compilers with
non-standard
ABIs that place the Vptr in a different location, or use other means
of dispatch.

I am happy to work on this if you now a serious platform that breaks
my assumption.

Cheers,

    Gabor



>
> 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.dut... at rapidmind.com>
>    RapidMind Inc.
>    phone: +1 519 885 5455 x116 -- fax: +1 519 885 1463
>
> _______________________________________________
> LLVM Developers mailing list
> LLVM... at cs.uiuc.edu        http://llvm.cs.uiuc.eduhttp://lists.cs.uiuc.edu/mailman/listinfo/llvmdev




More information about the llvm-dev mailing list