I try to build an application which uses pthreads and __m128 SSE type. According to GCC manual, default stack alignment is 16 bytes. In order to use __m128, the requirement is the 16-byte alignment.
My target CPU supports SSE. I use a GCC compiler which doesn't support runtime stack realignment (e.g. -mstackrealign). I cannot use any other GCC compiler version.
My test application looks like:
#include <xmmintrin.h>
#include <pthread.h>
void *f(void *x){
__m128 y;
...
}
int main(void){
pthread_t p;
pthread_create(&p, NULL, f, NULL);
}
The application generates an exception and exits. After a simple debugging (printf "%p", &y), I found that the variable y is not 16-byte aligned.
My question is: how can I realign the stack properly (16-byte) without using any GCC flags and attributes (they don't help)? Should I use GCC inline Assembler within this thread function f()?
Allocate on the stack an array that is 15-bytes larger than sizeof(__m128)
, and use the first aligned address in that array. If you need several, allocate them in an array with a single 15-byte margin for alignment.
I do not remember if allocating an unsigned char
array makes you safe from strict aliasing optimizations by the compiler or if it only works only the other way round.
#include <stdint.h>
void *f(void *x)
{
unsigned char y[sizeof(__m128)+15];
__m128 *py = (__m128*) (((uintptr_t)&y) + 15) & ~(uintptr_t)15);
...
}
This shouldn't be happening in the first place, but to work around the problem you can try:
void *f(void *x)
{
__m128 y __attribute__ ((aligned (16)));
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With