Linux 32-bit build fails with "inlining failed" error

I’m building v5.2.1 (but same failure occurs in 5.3rc02) on an up-to-date Debian Linux machine. GCC is version 11.2, CMake is 3.22.1

My machine is actually an AMD64. I can build the 64-bit version without trouble. But I have a 32-bit chroot that I have in the past used to build 32-bit software.

Using a simple “cmake; make” sequence – i.e. all options are defaults, the build fails with the errors listed below. This is the first warning and first error; there are several similar errors following. It appears to me that there’s a problem with SSE instructions. Can anyone advise whether I need extra compiler flags to select the right instruction set?

I have tried using -march=i686 and recieved same result [the configuration invocation was “CFLAGS=-march=i686 CXXFLAGS=-march=i686 cmake …”].

[ 30%] Building CXX object Modules/Core/Common/src/CMakeFiles/ITKCommon.dir/itkImageRegionSplitterSlowDimension.cxx.o
In file included from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkMath.h:32,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkVector.hxx:21,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkVector.h:332,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkPoint.h:23,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkContinuousIndex.h:21,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkImageRegion.h:34,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkImageRegionSplitterBase.h:21,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkImageRegionSplitterSlowDimension.h:21,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/src/itkImageRegionSplitterSlowDimension.cxx:19:
/home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkMathDetail.h: In function ‘itk::int32_t itk::Math::Detail::RoundHalfIntegerToEven_32(double)’:
/home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkMathDetail.h:151:24: warning: SSE vector return without SSE enabled changes the ABI [-Wpsabi]
151 | return _mm_cvtsd_si32(_mm_set_sd(x));
| ^
In file included from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkMathDetail.h:37,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkMath.h:32,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkVector.hxx:21,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkVector.h:332,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkPoint.h:23,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkContinuousIndex.h:21,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkImageRegion.h:34,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkImageRegionSplitterBase.h:21,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/include/itkImageRegionSplitterSlowDimension.h:21,
from /home/steve/Packages/insighttoolkit/build-area/InsightToolkit-5.2.1/Modules/Core/Common/src/itkImageRegionSplitterSlowDimension.cxx:19:
/usr/lib/gcc/i686-linux-gnu/11/include/emmintrin.h:867:1: error: inlining failed in call to ‘always_inline’ ‘int _mm_cvtsd_si32(__m128d)’: target specific option mismatch

A Debian colleague pointed out the problem. It turns out that the SSE instructions are unconditionally enabled on i386, due to the following bit of itkConfigure.in. The initial comment makes me wonder if this entire passage was meant to be conditional on MSVC. Or at least the “defined(__i386__)” bit.

// Most compilers define __SSEn__ macros, but not MSVC.
// For 32 bit Intel with MSVC, check _M_IX86_FP.
// 64 bit Intel x86 always supports both 32 and 64 bit SSE2.

#if defined(__SSE2__) || defined(__x86_64__) || defined(_M_X64) || defined(__amd64)
#  define ITK_COMPILER_SUPPORTS_SSE2_64
#endif

#if defined(ITK_COMPILER_SUPPORTS_SSE2_64) || \
    defined(__i386__) || \
    (defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
#  define ITK_COMPILER_SUPPORTS_SSE2_32
#endif

People rarely build 32-bit version of anything nowadays, and therefore rarely think about it too. Can you alter that logic to work for your 32-bit environment, and then submit a PR?

1 Like

To be honest, the way I altered it was to completely remove the “defined(__i386__) ” line. Is that acceptable?

Probably :smiley:

If you submit a PR, CI will try to build your branch and then we will see if you broke something by that. But it is quite possible there was an error in 32-bit logic, as we don’t really test 32-bit builds any more.

I created a PR: BUG: Do not unconditionally assume SSE2 when building on i386 by smr99 · Pull Request #2955 · InsightSoftwareConsortium/ITK · GitHub

3 Likes