Is strict anti-aliasing only for the first element?

Using GCC 4.7.2, why does this call a strict alias:

#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;
}   

So far this is normal:

#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;
}   

This is just a gcc issue that is not exact, or am missing something about how a strict alias works.

Also, is there an easy way to get around this with __attribute__((__may_alias__)), or am I just perfectly casting char * to temp?

+4
source share
1 answer

I think this is just GCC's failure to catch the problem. This, of course, is UB (alias violation). Solve it using __attribute__((__may_alias__))easily:

typedef uint32_t __attribute__((__may_alias__)) u32ma;

then use u32mainstead uint32_tin the cast pointer.

+2
source

All Articles