Reputation: 341
I have a function in C with prototype void f(__m128i *x)
. Inside this function I now call _mm_shuffle_epi8(*x, MASK)
where MASK
is some constant __m128i
type. When I run the code I get a segmentation fault, and Valgrind reveals it is actually a general protection fault occurring on this line.
What might be the cause of this, and how do I get around it?
Small working example:
#include <wmmintrin.h>
#include <smmintrin.h>
#define BSWAP_MASK _mm_set_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
#define ALIGN(n) __attribute__ ((aligned(n)))
static inline void g(const unsigned char *in, unsigned char *out) {
__m128i tmp = _mm_load_si128 ((__m128i*)in);
_mm_store_si128((__m128i*)out, tmp);
}
void f(__m128i *res) {
g((unsigned char*)&res, (unsigned char*)&res);
*res = _mm_shuffle_epi8(*res, BSWAP_MASK);
}
int main() {
ALIGN(16) __m128i x = _mm_set_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
f(&x);
}
Upvotes: 1
Views: 937
Reputation: 64203
As suspected, you had alignment problems.
If you do not properly align your data, or use functions to load and store at unaligned addresses, the result is crash.
If you want to use unaligned addresses, then this fixes the issue :
static inline void g(const unsigned char *in, unsigned char *out) {
//__m128i tmp = _mm_load_si128 ((__m128i*)in);
__m128i tmp = _mm_loadu_si128 ((__m128i*)in);
//_mm_store_si128((__m128i*)out, tmp);
_mm_storeu_si128((__m128i*)out, tmp);
}
As for why the linker fails to make that variable properly aligned, see Are stack variables aligned by the GCC __attribute__((aligned(x)))? and the answers there.
If you are on linux, you could use posix_memalign() function.
Upvotes: 1