Ответ 1
Одна из причин возникновения сбоя на x86 связана с проблемами выравнивания. Я не звоню в своей системе, чтобы воспроизвести проблему, но я могу продемонстрировать ее на примере GCC.
Если вы сделаете что-то вроде:
/* Define a vector type of 16 characters. */
typedef char __attribute__ ((vector_size (16))) byte16;
/* Global pointer. */
char * foo;
byte16 test ()
{
return *(byte16 *)&foo[1];
}
Теперь, если вы скомпилируете его на вектор-совместимом x86 с помощью:
$ gcc -O3 -march=native -mtune=native a.c
Вы получите следующую сборку для тестирования:
test:
movq foo(%rip), %rax
vmovdqa 1(%rax), %xmm0
ret
Обратите внимание, что перемещение выравнивается, что, конечно, неправильно. Теперь, если вы встроили эту функцию в основную, и у вас будет что-то вроде:
int main ()
{
foo = __builtin_malloc (22);
byte16 x = *(byte16 *)&foo[1];
return x[0];
}
У вас все будет хорошо, и вы получите не выровненную инструкцию. Это своего рода ошибка, которая не имеет очень хорошего исправления в компиляторе, поскольку для этого потребуются межпроцедурные оптимизации с добавлением новых структур данных и т.д.
Происхождение проблемы состоит в том, что компилятор предполагает, что векторные типы выровнены, поэтому, когда вы разыскиваете массив выровненных векторных типов, вы можете использовать выровненный ход. В качестве обходного пути для проблемы в GCC можно определить неглавный векторный тип, например:
typedef char __attribute__ ((vector_size (16),aligned (1))) unaligned_byte16;
И используйте его для разыменования неизменной памяти.
Я не уверен, что вы столкнулись именно с этой проблемой в своей настройке, но это то, что я бы рекомендовал проверить, проверив вывод сборки из вашего компилятора.