Last Updated: February 20, 2016
·
940
· dtcaciuc

Dangers of LLVM vector legalization

For performance reasons, LLVM might map <3 x double> type to a pair of _m128d (on x8664), effectively expanding the type width by one element. This breaks the program if memory block is allocated as array of doubles under assumption that each vector is 3 elements wide and then casted to the vector type.

Eg, the following program compiled with Clang:

#include <stdio.h>

typedef double double3 __attribute__((ext_vector_type(3)));

int main(void) {

    double a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    double b[] = {0, 0, 0, 0, 0, 0, 0, 0};

    ((double3 *)b)[0] = ((double3 *)a)[0];
    ((double3 *)b)[1] = ((double3 *)a)[1];

    printf("%lf %lf %lf %lf %lf %lf\n",
           b[0], b[1], b[2], b[3], b[4], b[5]);

    return 0;
}

produces the following:

1.000000 2.000000 3.000000 0.000000 5.000000 6.000000

Element 4 maps into the widened space and gets skipped over.