Это на самом деле не проблема NEON, это проблема, C, и вопрос:
vld1_lane_s32((int32_t const *) pTempMem , i32x2_offset, 0);
Кастинг указатель является сообщение компилятора говоря: «Эй, я знаю, это выглядит плохо, но поверь мне, я действительно знаю, что я делаю ». Преобразование указателя типа A в указатель на тип B, если указатель не имеет подходящего выравнивания для типа B, дает неопределенное поведение. Поэтому компилятор может предположить, что аргумент vld_1_lane_s32
всегда выровнен по 32 битам, потому что нет никакого действительного способа, которым это не могло быть (и вы пообещали, что знаете, что делаете), поэтому он испускает инструкцию с помощью подсказка выравнивания.
Теперь вы можете играть с вариантами, пытаясь получить различное неопределенное поведение, соответствующее тому, что вы хотите, но это просто связано с проблемой, а не фиксирует ее. То, что базовый набор инструкций NEON может поддерживать несвязанные обращения, не влияет на определение языка C и ограничений по выравниванию данных.
Я не знаком с тем, как умный LLVM, поэтому я не уверен, если просто опуская указатель бросание будет работать (технически, позволяет C превращающего char *
к любому другому типу указателя данных, так что должны быть способный самостоятельно сортировать выравнивание). В противном случае решение должно использовать соответствующую операцию vld*_u8
для загрузки данных в вектор по правильному типу, а затем передать это с помощью vreinterpret_s32_u8
после того, как оно находится в регистре.
Я бы понял, если компилятор выпустил инструкции с подсказками выравнивания, и программа просто взяла ошибку выравнивания во время выполнения, но компилятор, фактически генерирующий код для доступа к другому адресу, чем тот, который указан, звучит очень странно. Можете ли вы добавить код (и, возможно, соответствующую разборку) к вопросу, чтобы сделать более понятным, что на самом деле происходит здесь? – Notlikethat
@Notlikethat Мой код: «char TempMemory [32] = {0}; \t \t char * pTempMem = TempMemory; pTempMem + = 7; \t int32x2_t i32x2_value = vld1_lane_s32 ((int32_t const *) pTempMem, i32x2_offset, 0); ' Эквивалент узел для внутренней должен быть VLD1.32 {d0 [0]}, [pTempMem] Но компилятором сборка VLD1.32 {d0 [0]}, [pTempMem: 32] – srat
Пожалуйста [ отредактируйте сам вопрос] (http://stackoverflow.com/posts/31176671/edit), а не размещайте важные комментарии в комментариях. Особенно в случае кода. – Notlikethat