Skip to content

Commit b33e591

Browse files
jessey-gitlgritz
authored andcommitted
build: Add appropriate compiler defines and flags for SIMD with MSVC (#4266)
This should address the following 2 issues when using MSVC: - MSVC does not set defines like `__SSE2__` or `__SSE4_2__` etc. we must do that ourselves - MSVC uses the `/arch` flag differently than other compilers and it should be set only once The ramifications of not having those defines set basically means that OIIO won't notice any SIMD is possible. For MSVC the /arch flag only controls which instruction set the compiler may use when generating code "on its own". For example, the x64 compiler by default will use SSE2 whenever possible when its generating code but when using `/arch:AVX` it will produce AVX code as it sees fit. NOTE: case matters here too! "avx" does not work but "AVX" does. However, if the source code uses intrinsics, MSVC will happily use those instead. In fact it's possible to use `avx512` intrinsics without specifying any /arch flag at all and it will happily generate corresponding avx512 code. This is much different than say GCC where, in order to use intrinsics at all, you must specify the corresponding flags allowing you to do so for the arch in question. Fixes #4265 Existing simd_test.cpp should be sufficient I think. In addition to those, I've verified the below locally: Currently: when using `-DUSE_SIMD="sse4.2,avx2"` to build, we get the wrong `build:simd` flags: `sse2` After: using the same flags as above: `sse2,sse3,ssse3,sse41,sse42,avx,avx2` --------- Signed-off-by: Jesse Yurkovich <jesse.y@gmail.com>
1 parent 29334c2 commit b33e591

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

src/cmake/compiler.cmake

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,29 @@ if (NOT USE_SIMD STREQUAL "")
302302
if (USE_SIMD STREQUAL "0")
303303
set (SIMD_COMPILE_FLAGS ${SIMD_COMPILE_FLAGS} "-DOIIO_NO_SIMD=1")
304304
else ()
305+
set(_highest_msvc_arch 0)
305306
string (REPLACE "," ";" SIMD_FEATURE_LIST ${USE_SIMD})
306307
foreach (feature ${SIMD_FEATURE_LIST})
307308
message (VERBOSE "SIMD feature: ${feature}")
308309
if (MSVC OR CMAKE_COMPILER_IS_INTEL)
309-
set (SIMD_COMPILE_FLAGS ${SIMD_COMPILE_FLAGS} "/arch:${feature}")
310+
if (feature STREQUAL "sse2")
311+
list (APPEND SIMD_COMPILE_FLAGS "/D__SSE2__")
312+
endif ()
313+
if (feature STREQUAL "sse4.1")
314+
list (APPEND SIMD_COMPILE_FLAGS "/D__SSE2__" "/D__SSE4_1__")
315+
endif ()
316+
if (feature STREQUAL "sse4.2")
317+
list (APPEND SIMD_COMPILE_FLAGS "/D__SSE2__" "/D__SSE4_2__")
318+
endif ()
319+
if (feature STREQUAL "avx" AND _highest_msvc_arch LESS 1)
320+
set(_highest_msvc_arch 1)
321+
endif ()
322+
if (feature STREQUAL "avx2" AND _highest_msvc_arch LESS 2)
323+
set(_highest_msvc_arch 2)
324+
endif ()
325+
if (feature STREQUAL "avx512f" AND _highest_msvc_arch LESS 3)
326+
set(_highest_msvc_arch 3)
327+
endif ()
310328
else ()
311329
set (SIMD_COMPILE_FLAGS ${SIMD_COMPILE_FLAGS} "-m${feature}")
312330
endif ()
@@ -318,6 +336,20 @@ if (NOT USE_SIMD STREQUAL "")
318336
add_compile_options ("-ffp-contract=off")
319337
endif ()
320338
endforeach()
339+
340+
# Only add a single /arch flag representing the highest level of support.
341+
if (MSVC OR CMAKE_COMPILER_IS_INTEL)
342+
if (_highest_msvc_arch EQUAL 1)
343+
list (APPEND SIMD_COMPILE_FLAGS "/arch:AVX")
344+
endif ()
345+
if (_highest_msvc_arch EQUAL 2)
346+
list (APPEND SIMD_COMPILE_FLAGS "/arch:AVX2")
347+
endif ()
348+
if (_highest_msvc_arch EQUAL 3)
349+
list (APPEND SIMD_COMPILE_FLAGS "/arch:AVX512")
350+
endif ()
351+
endif ()
352+
unset(_highest_msvc_arch)
321353
endif ()
322354
add_compile_options (${SIMD_COMPILE_FLAGS})
323355
endif ()

0 commit comments

Comments
 (0)