Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

298
Views
_mm256_slli_si256: error "last argument must be an 8-bit intermediate"

I have the following problem (g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4):

When I use _mm256_slli_si256() directly, such as:

__m256i x = _mm256_set1_epi8(0xff);
x = _mm256_slli_si256(x, 3);

the code compiles without problem (g++ -Wall -march=native -O3 -o shifttest shifttest.C).

However, if I wrap it into a function

__m256i doit(__m256i x, const int imm)
{
  return _mm256_slli_si256(x, imm);
}

the compiler complains that

/usr/lib/gcc/x86_64-linux-gnu/4.8/include/avx2intrin.h: In function '__m256i doit(__m256i, int)':
/usr/lib/gcc/x86_64-linux-gnu/4.8/include/avx2intrin.h:651:58: error: the last argument must be an 8-bit immediate
   return (__m256i)__builtin_ia32_pslldqi256 (__A, __N * 8);

regardless of whether the function is used or not.

This can't be a problem with the immediate operand, since the function doit() compiles if I use e.g. _mm256_slli_si32(x, imm) instead, and _mm256_slli_si32() also requires an immediate operand.

There is a related bug report on

https://gcc.gnu.org/bugzilla/show_bug.cgi?format=multiple&id=54825

but it is quite old (2012) and relates to gcc 4.8.0, so I thought the patch would be have been incorporated into g++ 4.8.4 already.

Is there a workaround for this problem?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

The argument indicating the number of bits to shift must be a compile-time constant, as it is encoded as an immediate value in the instruction (i.e. not loaded from a register; the actual shift value is part of the instruction encoding). As long as you use it directly, like this:

__m256i x = _mm256_set1_epi8(0xff);
x = _mm256_slli_si256(x, 3);

then the compiler sees the shift value as a compile-time constant, 3. However, when in the context of your wrapping function:

__m256i doit(__m256i x, const int imm)
{
  return _mm256_slli_si256(x, imm);
}

there is no way for the compiler to infer the value of imm at compile time, which is required in order for it to synthesize the shift instruction. The fact that imm is a const int doesn't mean that its value is known at compile time, only that the semantics of the language don't allow it to be modified within the doit() function scope.

It's possible that if doit() were to be inlined by the compiler, then it may be able to statically determine the value of imm and therefore compile successfully, but that may be going too far out on a limb.

If you're using C++, another option would be to make doit() a function template with an argument indicating the shift size, like this:

template <int Shift>
__m256i doit(__m256i x)
{
  return _mm256_slli_si256(x, Shift);
}
over 4 years ago · Santiago Trujillo Report

0

The problem is due to your function being public (i.e. callable by functions in other C/C++ modules). If you declare it as static (or inline), the compiler will not do code-generation for this function, and you won't get an error.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!