If I generate IR using 'vector' types, for example, if my code assembles IR like this:
define <4 x float> @simd_mul(<4 x float>, <4 x float>) {
%3 = fmul <4 x float> %0, %1
ret <4 x float> %3
}
I assume that when I JIT, it will generates the best SIMD instructions available on the host it's running on? For example, when running on a machine supporting SSE, it does seem to generate SSE instructions, and this successfully turns into a function callable from C with a signature that looks like
__m128 simd_mul (__m128 a, __m128 b);
But the vector documentation is a little sketchy, and I am not sure about a few things:
* Will it really autodetect and use the best SIMD available on my machine? (For example, SSE4.2 vs SSE2, etc.?) Is there anything I need to tell the JIT or the ExecutionEngine to make it use a particular instruction set? (The only case I care about is to generate the best code for the host it's currently running on.)
* Is there any difference in vector functionality of old JIT versus MCJIT? (Yes, I know that starting in 3.6, it'll be only MCJIT.)
* What happens if it runs on a machine without SSE? Is using vectors an error, or will it just generate the equivalent scalar code automatically? If it generates scalar code, what is the function signature, as it would appear to be called from a C function, on a machine without __m128?
* What happens to vector types of length not equal to the machine's SIMD length? If I defined a <3 x float>, would it always generate scalar code, or would it pad to a 4xfloat and generate SSE instructions? Or is it not even allowed?
Thanks, and apologies if I've missed the documentation where all this is spelled out.