diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3200,6 +3200,33 @@ vector length is unknown at compile time. Vector types are considered :ref:`first class `. +:Memory Layout: + +In general vector elements are laid out in memory in the same way as +:ref:`array types `. Such an anology works fine as long as the vector +elements are byte sized. However, when the elements of the vector isn't byte +sized it gets a bit more complicated. One way to describe the layout is by +describing what happens when a vector such as is bitcasted to an +integer type with N*M bits, and then following the rules for storing such an +integer to memory. + +A bitcast from a vector type to a scalar integer type will see the elements +being packed toghether (without padding). The order in which elements are +inserted in the integer depends on endianess. For little endian element zero +is put in the least significant bits of the integer, and for big endian +element zero is put in the most significant bits. + +Using a vector such as ```` as an example, after +bitcasting it to i16 we either get the hexadecimal value ``0x4321`` (for +little endian) or ``0x1234`` (for big endian). When stored to memory the byte +at the memory address ``X`` will be either ``0x21`` or ``0x12`` depending on +endianess. And the byte at address ``X+1`` will either be ``0x43`` or +``0x34``. + +When ```` isn't evenly divisible by the byte size the memory layout is +unspecified. + + :Syntax: :: @@ -10603,14 +10630,19 @@ To convert pointers to other types, use the :ref:`inttoptr ` or :ref:`ptrtoint ` instructions first. +There is a caveat for bitcasts involving vector types in relation to +endianess. For example ``bitcast <2 x i8> to i16`` puts element zero +of the vector in the least significant bits of the i16 for little-endian while +element zero ends up in the most significant bits for big-endian. + Example: """""""" .. code-block:: text - %X = bitcast i8 255 to i8 ; yields i8 :-1 - %Y = bitcast i32* %x to sint* ; yields sint*:%x - %Z = bitcast <2 x int> %V to i64; ; yields i64: %V + %X = bitcast i8 255 to i8 ; yields i8 :-1 + %Y = bitcast i32* %x to sint* ; yields sint*:%x + %Z = bitcast <2 x int> %V to i64; ; yields i64: %V (depends on endianess) %Z = bitcast <2 x i32*> %V to <2 x i64*> ; yields <2 x i64*> .. _i_addrspacecast: