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,63 @@ 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 aren'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, together +with the analogy that we can replace a vector store by a bitcast followed by +an integer store, we ge this for big endian: + +.. code-block:: llvm + + %val = bitcast <4 x i4> to i16 + + ; Bitcasting from a vector to an integral type can be seen as + ; concatenating the values: + ; %val now has the hexadecimal value 0x1235. + + store i16 %val, i16* %ptr + + ; In memory the content will be (8-bit addressing): + ; + ; [%ptr + 0]: 00010010 (0x12) + ; [%ptr + 1]: 00110101 (0x35) + +The same example for little endian: + +.. code-block:: llvm + + %val = bitcast <4 x i4> to i16 + + ; Bitcasting from a vector to an integral type can be seen as + ; concatenating the values: + ; %val now has the hexadecimal value 0x5321. + + store i16 %val, i16* %ptr + + ; In memory the content will be (8-bit addressing): + ; + ; [%ptr + 0]: 01010011 (0x53) + ; [%ptr + 1]: 00100001 (0x21) + +When ```` isn't evenly divisible by the byte size the exact memory layout +is unspecified (just like it is for an integral type of the same size). This +is because different targets could put the padding at different positions when +the type size is smaller than the types store size. + :Syntax: :: @@ -10604,14 +10661,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: