https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114039
Bug ID: 114039
Summary: Unroll loops with SSE/AVX intrinsic where an immediate
argument is a loop var
Product: gcc
Version: 13.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: daniil.iaitskov at soostone dot com
Target Milestone: ---
Lots of SSE/AVX intrinsic functions can accept only literal constants in
arguments.
Current workaround is turning a variable with a small cardinality into a switch
wrapped with a macro. I think extending unrolling semantic to this case should
help a lot with reducing code boilerplate.
Program expected to pass compilation:
```
#include <stdio.h>
#include <immintrin.h>
inline __m128i testUnrollSse(__m128i x, __m128i d, int n) {
for (int i = n; i <= n; ++i) { // loop does always just a single iteration
return _mm_srli_si128(x, i);
}
return d;
}
__m128i foo(int i, __m128i x, __m128i d) {
if (i < 16) {
return testUnrollSse(x, d, i);
}
return d;
}
```
Compiler options: gcc -mavx2 -O3
```
Output of x86-64 gcc 13.2 (Compiler #1)
In file included from
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/include/xmmintrin.h:1322,
from
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/include/immintrin.h:31,
from <source>:2:
In function '_mm_srli_si128',
inlined from 'testUnrollSse' at <source>:6:12,
inlined from 'foo' at <source>:13:16:
/opt/compiler-explorer/gcc-13.2.0/lib/gcc/x86_64-linux-gnu/13.2.0/include/emmintrin.h:1229:19:
error: the last argument must be an 8-bit immediate
1229 | return (__m128i)__builtin_ia32_psrldqi128 (__A, __N * 8);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compiler returned: 1
```
Expected code:
```
switch(i) {
case 1: return _mm_srli_si128(x, 1);
case 2: return _mm_srli_si128(x, 2);
// ...
case 16: return _mm_srli_si128(x, 16);
defaut:
fprintf(stderr, "Panic ....", __FILE__, __LINE__, i);
exit(-1);
```