是否只对第一个元素进行严格别名?

时间:2014-12-06 04:52:18

标签: c gcc casting simd

使用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;
}   

这只是一个gcc不准确的问题,还是我错过了一些关于严格别名的工作原理。

另外,使用__attribute__((__may_alias__))是否有一种简单的方法可以解决这个问题,或者我是否也可以将其转换为临时字符*?

1 个答案:

答案 0 :(得分:2)

我认为这只是GCC未能解决的问题。它肯定是UB(锯齿违规)。使用__attribute__((__may_alias__))解决它很容易:

typedef uint32_t __attribute__((__may_alias__)) u32ma;

然后在指针强制转换中使用u32ma而不是uint32_t