2014-12-06 4 views
4

Использования GCC 4.7.2, почему это вызывает строгое нарушение псевдонима:Является строгим псевдонимом только для первого элемента?

#include <stdint.h> 
#include "emmintrin.h" 

int f(){ 
    int ret = 0; 

    __m128i vec_zero __attribute__ ((aligned (16))) = _mm_set1_epi32(0); 
    __m128i vec_one __attribute__ ((aligned (16))) = _mm_set1_epi32(1); 
    __m128i vec_result __attribute__ ((aligned (16))); 
    vec_result = _mm_cmpgt_epi32(vec_zero, vec_one); 
    ret += (((uint32_t*)&vec_result)[0] != 0); 
    ret += (((uint32_t*)&vec_result)[1] != 0); 
    return ret; 
} 

Хотя это нормально:

#include <stdint.h> 
#include "emmintrin.h" 

int f(){ 
    int ret = 0; 

    __m128i vec_zero __attribute__ ((aligned (16))) = _mm_set1_epi32(0); 
    __m128i vec_one __attribute__ ((aligned (16))) = _mm_set1_epi32(1); 
    __m128i vec_result __attribute__ ((aligned (16))); 
    vec_result = _mm_cmpgt_epi32(vec_zero, vec_one); 
// ret += (((uint32_t*)&vec_result)[0] != 0); 
    ret += (((uint32_t*)&vec_result)[1] != 0); 
    return ret; 
} 

Является ли это просто вопрос НКА не является точной или я отсутствую что-то о том, как работает строгий псевдоним.

Кроме того, есть ли простой способ обойти это с использованием __attribute__((__may_alias__)), или я просто так же отлично отбрасываю на temp char *?

+0

'__attribute__ ((выровненный (16)))' кажется бесполезным. –

+0

@MarcGlisse, почему вы так говорите? Я думал, что аргументы '_mm_cmpgt_epi32' должны быть выровнены. – user1794469

+1

'__m128i' уже подразумевает подходящее выравнивание (в противном случае было бы очень больно использовать). –

ответ

2

Я думаю, что это просто неудача GCC, чтобы поймать проблему. Это, конечно, UB (нарушение псевдонимов). Решая его с __attribute__((__may_alias__)) легко, хотя:

typedef uint32_t __attribute__((__may_alias__)) u32ma; 

затем использовать u32ma вместо uint32_t в указателе гипсе.

Смежные вопросы