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
template
using Addr32 = __attribute((address_space(32))) T;
void Debug(Addr32* p1, int* p2, int* p3, Addr32* p4);
Addr32 i1 = 1234;
Addr32* 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