[LLVMdev] PointerIntPair causing trouble

Nicolas Capens nicolas at capens.net
Sat May 2 07:24:58 PDT 2009


Hi Stefanus,

 

I had actually tried that already, but my project kept crashing. However,
after giving it a second try I noticed that the crash was happening
elsewhere this time. After disabling the GVN optimization pass everything
worked fine. Somewhere between revision 67979 and 67996 the bug that was
causing GVN to fail was fixed.

 

So thanks for tracking this down!

 

I agree that option (2) is a good solution for now. But in my humble opinion
the whole idea of storing other information in pointers is not very robust.
One alternative would be to have a global store of all Value objects. They
can then be identified with just an index instead of a pointer. This index
can be stored in a bitfield that is smaller than 32-bit, leaving bits
available for additional data.

 

Cheers,

 

Nicolas

 

From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] On
Behalf Of Stefanus Du Toit
Sent: zaterdag 2 mei 2009 0:41
To: LLVM Developers Mailing List
Subject: Re: [LLVMdev] PointerIntPair causing trouble

 

Hi Nicolas,

 

Looks like Preston and I have found the cause of the problem. The issue is
with PointerLikeTypeTraits<T*>::NumLowBitsAvailable. This is set to 3, which
basically assumes that unless the traits are specialized for a particular
pointer type, objects of that type are allocated with malloc() and aligned
to 8 bytes.

 

While PointerLikeTypeTraits is overloaded for Use*, it is not overloaded for
User*. lib/VMCore/Use.cpp uses a PointerIntPair<User*, 1, Tag>, and things
go bad. Users are typically allocated in an array after a bunch of Uses,
which are 12 bytes in size, so they may actually only be aligned to 4 bytes.

 

The attached patch (which I don't intend to commit, it's just a workaround)
works around this simply by dropping this down to 2 bits, which gets us past
our problem on Windows. I would appreciate if you could verify that this
works for you as well.

 

To actually solve this properly I see two main options:

 

(1) we could specialize PointerLikeTypeTraits for User*, and leave the
default value of NumLowBitsAvailable at 3.

(2) we could drop the default NumLowBitsAvailable to 2 (or even use _alignof
and similar compiler-specific extensions to determine it), and allow classes
that assert that they are only ever allocated through malloc to relax it
back up to 3.

 

My preference would be for option (2), due to the difficulty of tracking
this bug down, and the risk of future similar bugs happening. However, I'd
appreciate some feedback from the LLVM developer community on this. Please
let me know what you think, and I'll be happy to prepare a patch.

 

I'm still wondering why this wasn't an issue on other platforms. One
possibility is that Use is being bumped up to 16 bytes in size, and thus
Users never get placed at less than an 8-byte boundary. However, in that
case, the whole point of the "use diet" optimization is lost! I'll
investigate and try to find out.

 

I'm also still not sure why the assertion in PointerIntPair::setPointer()
did not get triggered by the User::allocHungOffUses() implementation in
Use.cpp. Perhaps the assertion is wrong (it looks reasonable, though) or
perhaps there is something else going on I haven't seen yet. I'll look into
this some more as well.

 

Let me know if the workaround works for you, and I'd appreciate feedback
from anyone (Chris? Gabor?) as to how best to proceed.

 

Thanks!

 

Stefanus

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090502/5ae048ed/attachment.html>


More information about the llvm-dev mailing list