Jeroen Dobbelaere
2014-Apr-04 08:54 UTC
[LLVMdev] 32bit pointers on a (pure) 64bit architecture
Hi Hal, On Fri, Apr 4, 2014 at 12:44 AM, Hal Finkel <hfinkel at anl.gov> wrote:> ----- Original Message ----- > > From: "Jeroen Dobbelaere" <jeroen.dobbelaere at gmail.com> > [... ] > > I am trying to get llvm working for an architecture that has 64bit > > registers, but 32bit addresses. > > Because of that, I want the pointers to also be 32bit, although they > > will live in a 64 bit register. > > > [...] >I don't understand why you're doing this. If the pointers live in 64-bit> registers, why don't you just consider them to be 64-bit pointers? The fact > that the upper 32 bits will always be zero does not seem like something > you'd need to worry about (although there are certainly some optimizations > that can be done later). Frontend issues, like the fact that ptrdiff_t is > only 32 bits, seem like an independent concern. > > -Hal > >The main reason to do this, is to use less space for a pointer. This reflects then in the size of structs that use pointers etc... As the layout of a structure is based on the DataLayout string, Both the DataLayout of clang and of the backend need to be kept in sync: - When I provide 32bit pointers to clang, but 64bit pointers to the backend, the frontend and middle end are indeed making use of 32bit pointers. But from the moment that a pointer member needs to be accessed (by the backend), the offset is wrong (as it suddenly assumes 64bit pointers). (Like in 'struct Foo { int bar; struct Foo* next; struct Foo* prev; } ) So, that's why I believe the the right way to handle this, is by specifying "p:32:32:32" in both datalayout strings. The fact that because of this, llvm is producing a selection dag that cannot be handled by legalization seems more like a bug to me.. and I would like to find out what the recommend way is to fix this. [...] Greetings, Jeroen Dobbelaere -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140404/c98f109d/attachment.html>
----- Original Message -----> From: "Jeroen Dobbelaere" <jeroen.dobbelaere at gmail.com> > To: "Hal Finkel" <hfinkel at anl.gov> > Cc: LLVMdev at cs.uiuc.edu > Sent: Friday, April 4, 2014 3:54:08 AM > Subject: Re: [LLVMdev] 32bit pointers on a (pure) 64bit architecture > > > > > Hi Hal, > > On Fri, Apr 4, 2014 at 12:44 AM, Hal Finkel < hfinkel at anl.gov > > wrote: > > > > ----- Original Message ----- > > From: "Jeroen Dobbelaere" < jeroen.dobbelaere at gmail.com > > [... ] > > > > > I am trying to get llvm working for an architecture that has 64bit > > registers, but 32bit addresses. > > Because of that, I want the pointers to also be 32bit, although > > they > > will live in a 64 bit register. > > > [...] > > > > I don't understand why you're doing this. If the pointers live in > 64-bit registers, why don't you just consider them to be 64-bit > pointers? The fact that the upper 32 bits will always be zero does > not seem like something you'd need to worry about (although there > are certainly some optimizations that can be done later). Frontend > issues, like the fact that ptrdiff_t is only 32 bits, seem like an > independent concern. > > -Hal > > > > > > > > > The main reason to do this, is to use less space for a pointer. This > reflects then in the size of structs that use pointers etc... > > As the layout of a structure is based on the DataLayout string, Both > the DataLayout of clang and of the backend need to be kept in sync: > - When I provide 32bit pointers to clang, but 64bit pointers to the > backend, the frontend and middle end are indeed making use of 32bit > pointers. But from the moment that a pointer member needs to be > accessed (by the backend), the offset is wrong (as it suddenly > assumes 64bit pointers). > > > (Like in 'struct Foo { int bar; struct Foo* next; struct Foo* prev; } > ) > > > So, that's why I believe the the right way to handle this, is by > specifying "p:32:32:32" in both datalayout strings.Agreed; but what does your *ISelLowering::getPointerTy() function look like? Did you override the default implementation? I wonder if returning MVT::i64 from this function will make things work for you. -Hal> The fact that because of this, llvm is producing a selection dag that > cannot be handled by legalization seems more like a bug to me.. and > I would like to find out what the recommend way is to fix this. > [...] > > > Greetings, > > Jeroen Dobbelaere
Jeroen Dobbelaere
2014-Apr-04 15:07 UTC
[LLVMdev] 32bit pointers on a (pure) 64bit architecture
Hi Hal, On Fri, Apr 4, 2014 at 1:22 PM, Hal Finkel <hfinkel at anl.gov> wrote:> [..]> Agreed; but what does your *ISelLowering::getPointerTy() function look > like? Did you override the default implementation? I wonder if returning > MVT::i64 from this function will make things work for you. > > -Hal > >I actually missed implementing this one. But, depending on the testcase that I use, implementing it has no or worse effect: I now get assertion errors complaining of different value sizes, coming from the difference between the datalayout (ptrsize:i32) and the pointerty (size overruled to i64). in SelectionDag::InferPtrAlignment. I also found out the this method is not called at all (for my (failing) tests) during the initial selection dag buildup. Note: - most of my testing is done on llvm-3.3, but I verified that the same issues are there for llvm-3.4 - I did implement: virtual MVT getScalarShiftAmountTy(EVT LHSTy) const { return MVT::i64; } although I have no good idea why the default for that is mapped to the pointer type... In the following sample: - if full 64bit pointers are used, XXXi32 will be 'i64' and everything legalizes/compiles fine - if 32bit pointers are used, XXXi32 will be 'i32' and legalization fails. *** IR Dump After Module Verifier *** ; Function Attrs: nounwind define void @foo(i32 %lhs) #0 { entry: store i32 %lhs, i32* @g_bar, align 4, !tbaa !0 ret void } Computing probabilities for entry Initial selection DAG: BB#0 'foo:entry' SelectionDAG has 9 nodes: 0xbb93e8c: ch = EntryToken [ORD=1] 0xbbb8428: XXXi32 = Constant<0> 0xbb93e8c: <multiple use> 0xbb93e8c: <multiple use> 0xbbb8208: i64 = Register %vreg0 [ORD=1] 0xbbb8290: i64,ch = CopyFromReg 0xbb93e8c, 0xbbb8208 [ORD=1] 0xbbb8318: i32 = truncate 0xbbb8290 [ORD=1] 0xbbb83a0: XXXi32 = GlobalAddress<i32* @g_bar> 0 [ORD=1] 0xbbb84b0: XXXi32 = undef [ORD=1] 0xbbb8538: ch = store 0xbb93e8c, 0xbbb8318, 0xbbb83a0, 0xbbb84b0<ST4[@g_bar](tbaa=!"int")> [ORD=1] 0xbbb85c0: ch = PDISD::NODE_RET_FLAG 0xbbb8538 ----- Is this difference indeed what we would need to expect at this level ? - should we learn the selection dag creator to use the first larger or equal valid type (i64) here ? - or should we make sure that the legalization phase accepts the mix of types that is produced in that case ? Greetings, -- Jeroen Dobbelaere -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140404/f71fbeac/attachment.html>