[cfe-dev] Mixed 32b/64b pointers in same translation unit

Patrik Eklöf via cfe-dev cfe-dev at lists.llvm.org
Thu Feb 2 08:05:53 PST 2017


Dear community,

I am looking at trying to use clang in such a way that it is possible to use both 32-bit and 64-bit pointers in the same translation unit. Is this currently supported?

I would like to enable it on a per-pointer basis, and it would be ideal if it is part of the type. I am thinking that one would do something like...

[[ptr_32]] int* p;

...or the like to tell the compiler specifically that it is a 32-bit pointer (the rest will be 64-bit). I am compiling to a 64-bit target, so all pointers should natively be 64-bit.

I've been looking over the source a little, and see references to address space and an attribute __address_space__ that enables one to choose the address space for variables. It seems that depending on the address space, different sizes for pointers can be used. I tried modifying the DataLayout::reset function (I realize I should probably modify the targets instead of the layout class itself) to add another entry to the Pointers vector:

setPointerAlignment(0, 8, 8, 8);
setPointerAlignment(4, 4, 4, 4);

...and using the address space extension to pick out the right size for some pointers:

__attribute__((address_space(0))) int* HiIAmA64BitPtr{ (int*)0xFFFF'FFFF'FFFF'FFFF };
__attribute__((address_space(4))) int* HiIAmA32BitPtr{ (__attribute__((address_space(4))) int*)0xFFFF'FFFF'FFFF'FFFF };

But that did not appear to work. When running the code and printing the size of the variables, I see that they are both 8 bytes:

std::cout << "Size of 64-bit ptr: " << sizeof(HiIAmA64BitPtr) << std::endl; // Prints 8
std::cout << "Size of 32-bit ptr: " << sizeof(HiIAmA32BitPtr) << std::endl; // Prints 8

Furthermore, for some strange reason, if I print the LLVM IR using clang++ -S -emit-llvm, I see that all pointers seem to be 32 bits long even without using the address space extension. Yet, a long long variable (called Test here) has a 64-bit size:

target triple = "x86_64-pc-windows-msvc19.0.0"

@"\01?HiIAmA64BitPtr@@3PEAHEA" = global i32* inttoptr (i64 -1 to i32*), align 8
@"\01?HiIAmA32BitPtr@@3PEAHEA" = global i32 addrspace(4)* inttoptr (i64 -1 to i32 addrspace(4)*), align 8
@"\01?g_Test@@3_KA" = global i64 0, align 8

This seems very odd to me. Can someone point me in the right direction on how to approach this?

My command line for compiling:

clang++ "Test.cpp" -std=c++1z -Wall -fms-compatibility-version=19 -c -o Test.o && "link.exe" -out:Test.exe -defaultlib:libcmt -nologo Test.o

(For some reason, clang is unable to invoke the linker correctly on its own.)
Regards,
Patrik Eklöf

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170202/e3ebb4ef/attachment.html>


More information about the cfe-dev mailing list