5

I am trying to load images using stb_image.h but I am getting two compiler errors in the version of <emmintrin.h> provided by gcc. I figure that there is probably a compiler option that is needed but I haven't been able to find what it is.

Error codes:

/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include/emmintrin.h:1230:10: error: the last argument must be an 8-bit immediate
 1230 |   return (__m128i)__builtin_ia32_pslldqi128 (__A, __N * 8);
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include/emmintrin.h:1224:10: error: the last argument must be an 8-bit immediate
 1224 |   return (__m128i)__builtin_ia32_psrldqi128 (__A, __N * 8);
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Relevant code from <emmintrin.h>:

extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_srli_si128 (__m128i __A, const int __N)
{
  return (__m128i)__builtin_ia32_psrldqi128 (__A, __N * 8);
}

extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_slli_si128 (__m128i __A, const int __N)
{
  return (__m128i)__builtin_ia32_pslldqi128 (__A, __N * 8);
}

Edit: It has something to do with spdlog. I removed all includes of spdlog and changed my logging macros to nothing and it compiled successfully

Minimum reproducible example:

main.cpp

#include "pch.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

int main() {
    return 0;
}

pch.h:

#include <spdlog/spdlog.h>

cmakelists.txt:

cmake_minimum_required(VERSION 3.22)
project(untitled2)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_COMPILER /usr/bin/g++)

add_executable(untitled2 main.cpp stb_image.h pch.h)
target_precompile_headers(untitled2 PUBLIC pch.h)

add_subdirectory(spdlog)
target_link_libraries(untitled2 spdlog)
genpfault
  • 51,148
  • 11
  • 85
  • 139
Ceredia
  • 51
  • 4
  • 2
    [mcve] please! As a new user here, also take the [tour] and read [ask]. – Ulrich Eckhardt Jan 10 '22 at 19:46
  • If you don’t really care how exactly that crappy logging library broke these SSE2 intrinsics, and just want to compile your stuff — try restructuring your source code so that `emmintrin.h` (and ideally the complete `stb_image.h`, implementation included) is included into your CPP file before the header. – Soonts Jan 10 '22 at 23:11

1 Answers1

2

It happens when your program isn't compiling with optimizations but emmintrin.h is selecting the optimized versions of _mm_srli_si128 and _mm_slli_si128 because fmt (a dependency of spdlog) defines __OPTIMIZE__ here.

For more information, take a look at https://github.com/nothings/stb/discussions/1432#discussioncomment-4595273.

Possible workarounds:

  1. Disable precompiled headers for the translation unit that is implementing stb_image (for example, moving it to another CMake target (if CMake is being used))
  2. Undefine __OPTIMIZE__ on the translation unit that is implementing stb_image:
#if defined(__GNUC__) && !defined(NDEBUG) && defined(__OPTIMIZE__)
    #warning "Undefing __OPTIMIZE__ because of fmt"
    #undef __OPTIMIZE__
#endif

Feel free to remove the generated warning if you want.

OverShifted
  • 457
  • 1
  • 7
  • 17