Quantcast

Why is my 32-bit pointer treated like a 64-bit pointer?

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Why is my 32-bit pointer treated like a 64-bit pointer?

Ammarguellat, Zahira via cfe-dev

Hi all,

 

I’m trying to implement mixed 32/64-bit pointers in the same translation unit. But right now, clang is doing something I don’t understand why.

 

If I take this simple C++ code:

 

#include <cstdint>

 

template<typename T>

using Addr32 = __attribute((address_space(32))) T;

 

void Debug(Addr32<int>* p1, int* p2, int* p3, Addr32<int>* p4);

 

Addr32<int> i1 = 1234;

Addr32<int>* p1;

 

int main()

{

                             p1 = &i1;

                             static_assert(sizeof(p1) == 4);

}

 

And compile it, I get the following IR without optimizations:

 

@"\01?i1@@3HA" = addrspace(32) global i32 1234, align 4

@"\01?p1@@3PEAHEA" = global i32 addrspace(32)* null, align 4

 

; Function Attrs: norecurse nounwind uwtable

define i32 @main() #0

{

  store i32 addrspace(32)* @"\01?i1@@3HA", i32 addrspace(32)** @"\01?p1@@3PEAHEA", align 4

  ret i32 0

}

 

And with optimizations (-O3), it becomes

 

@"\01?i1@@3HA" = addrspace(32) global i32 1234, align 4

@"\01?p1@@3PEAHEA" = local_unnamed_addr global i32 addrspace(32)* null, align 8

 

; Function Attrs: norecurse nounwind uwtable

define i32 @main() local_unnamed_addr #0

{

  store i32 addrspace(32)* @"\01?i1@@3HA", i32 addrspace(32)** @"\01?p1@@3PEAHEA", align 8, !tbaa !8

  ret i32 0

}

 

Both of them produce the same assembly:

 

lea                       rcx, [rip + "?i1@@3HA"]

mov                    qword ptr [rip + "?p1@@3PEAHEA"], rcx

 

So even though I have a 32-bit pointer (static_assert(sizeof(p1) == 4)) and alignment 4 (in the debug version), it gets treated as a 64-bit pointer with alignment 8 in the assembly. Clang also somehow optimizes the pointer by aligning it on a 8-byte boundary when optimizing.

 

I’ve overridden TargetInfo::getPointerWidthV and TargetInfo::getPointerAlignV to properly return 32 bits for a pointer in address space 32. I’ve also modified the Pointers vector in the DataLayout to return 4 bytes for both size and alignment for address space 32. Is there something I’m missing? Why is clang treating the pointers as 64 bits?

 

Regards,

Patrik Eklöf

 

 


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why is my 32-bit pointer treated like a 64-bit pointer?

Ammarguellat, Zahira via cfe-dev
On 8 February 2017 at 06:08, Patrik Eklöf via cfe-dev
<[hidden email]> wrote:
> I’ve overridden TargetInfo::getPointerWidthV and
> TargetInfo::getPointerAlignV to properly return 32 bits for a pointer in
> address space 32.

Just about all that'll affect is sizeof/alignof and structure layout
algorithms. Things the C front-end handles.

> I’ve also modified the Pointers vector in the DataLayout
> to return 4 bytes for both size and alignment for address space 32. Is there
> something I’m missing? Why is clang treating the pointers as 64 bits?

That's closer to CodeGen, but I'm afraid the x86 backend just isn't
written to deal with different address-spaces having different pointer
sizes right now. Virtually all the choices it makes are based on a
simple "isTarget64BitLP64" check.

I'd expect it to be quite a lot of work in lib/Target/X86 to get this going.

Tim.
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Loading...