Visual C++ 2015 Release build hangs forever, trying to compile itk::Math::Floor

One of my colleagues encountered a Visual C++ 2015 compiler bug which causes the compiler to hang forever when it tries to instantiate BSplineInterpolationWeightFunction with TCoordRep = float and VSplineOrder = 1. Is it OK if I just add this template instantiation to https://github.com/Kitware/ITK/blob/master/Modules/Core/Common/test/itkBSplineInterpolationWeightFunctionTest.cxx as a “WIP” commit? I would like to know if the issue can be reproduced by the Build Robot. As follows:

template class itk::BSplineInterpolationWeightFunction<float, 2U, 1U>;

It appears to me that the issue is triggered by a Math::Floor call at:
https://github.com/Kitware/ITK/blob/v4.13.0/Modules/Core/Common/include/itkBSplineInterpolationWeightFunction.hxx#L119

Actually the issue can be reproduced without using any ITK, but doing something similar to itk::Math::Floor, as follows:

#include <emmintrin.h>

long long Floor_64(double x)
{
  return _mm_cvtsd_si64(_mm_set_sd(2 * x - 0.5)) >> 1;
}

float float32;
long long long64 = Floor_64(static_cast<double>(float32) - 0.0);

It appears that compiling this code takes forever, when using Visual C++ 2015 (Release, 64-bits). Is this a known issue?

The Visual Studio Build Robots are currently having health issues, so it would be better not to take one down at the moment. Once we move to GitHub, it would be tried.

It would be helpful to report the issue to the Visual Studio issue tracker.

Thanks for your reply, @matt.mccormick I hope the issue can be given a high priority.

FYI, I just posted at a Visual C++ forum: "VC++ 2015 x64 Release build (/O2) takes forever, trying to compile _mm_cvtsd_si64(_mm_set_sd(…)), a known compiler bug?"
https://social.msdn.microsoft.com/Forums/en-US/be92f3ae-8910-4709-9de5-4b8ba2b74968/vc-2015-x64-release-build-o2-takes-forever-trying-to-compile-mmcvtsdsi64mmsetsd?forum=vclanguage

1 Like

My proposed workaround for this compiler bug:
"COMP: Worked around endless VS2015 Release compilation on Math::Floor"
http://review.source.kitware.com/#/c/23046/

1 Like

Thank you for approving at merging my proposed workaround to ITK: https://itk.org/gitweb?p=ITK.git;a=commit;h=5788f5fe34f4825297880684eae12b6e65b70203

It was noted by Darran Rowe at https://social.msdn.microsoft.com/Forums/en-US/be92f3ae-8910-4709-9de5-4b8ba2b74968/vc-2015-x64-release-build-o2-takes-forever-trying-to-compile-mmcvtsdsi64mmsetsd?forum=vclanguage that the problem does not occur when Link Time Code Generation (LTCG) is enabled (compiler flag /GL). Is there any reason why ITK would not use LTCG? It appears to me that Whole Program Optimization is disabled for Visual C++ ITK projects, even for the Release configuration.

LTCG is enabled by default for Release configurations, when Visual C++ project created directly from Visual Studio (2013, 2015, 2017), through Visual Studio File menu, New, Project… It is recommended by Terry Mahaffey at https://github.com/TriangleCppDevelopersGroup/TerryMahaffeyCppTalk/blob/master/compiler.pptm

1 Like

Thank you for contributing the fix, @Niels_Dekker! :sunny:

That’s interesting.

I don’t think Whole Program Optimization is disabled – it is just not enabled :stuck_out_tongue:.

The benefits of LTCG will come when the application that uses ITK as a library links its final binary. So, this is something that client applications want to use. We could try to propagate this flag when ITK is built in Release so it is automatically added with ITK_REQUIRED_LINK_FLAGS.

1 Like

Maybe this Link Time Code Generation issue should eventually be solved by a revision of CMake itself. When CMake generates a Visual C++ project which does not explicitly specify any compiler flags, I think it should add LTCG by default, for Release configurations. As it is also the default for Visual C++ projects that are created directly by Visual Studio.

2 Likes

In the meantime I asked at the CMake mailing list whether CMake could add LTCG by default, for Release configurations:

[CMake] Link Time Code Generation (LTGC) by default, for Release configurations of Visual Studio projects?

The reply by Cristian Adam sounds hopeful: https://public.kitware.com/pipermail/cmake/2018-January/066971.html

1 Like

FYI, My CMake feature request on this issue is here: Link Time Code Generation (LTGC) by default, for Release configurations of Visual Studio projects https://gitlab.kitware.com/cmake/cmake/issues/17720

1 Like

Update on this topic: With the help of @brad.king, I made a patch to support enabling Link Time Code Generation (Whole Program Optimization) for Visual Studio, by means of a CMake property, INTERPROCEDURAL_OPTIMIZATION. This patch has just been merged (https://gitlab.kitware.com/cmake/cmake/issues/16748), and is scheduled to be included with CMake release 3.13.0

Note that the patch does not yet enable LTCG “by default”. You’d have to switch it on! The following code should enable LTCG for the Release configuration (which is what I would suggest people to do):

cmake_minimum_required( VERSION 3.13)
project( MyProject )
add_executable(MyProject MyMain.cpp MySource.cpp)
set_property(TARGET MyProject PROPERTY INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)

I think this could be an interesting option for both ITK users and ITK developers.

2 Likes