error C2164: '_mm_set_epi64x': intrinsic function not declared #1042

Closed
opened 2025-06-13 02:58:08 -05:00 by swiglu · 19 comments
swiglu commented 2025-06-13 02:58:08 -05:00 (Migrated from github.com)

xxhash v0.8.2

kernel-mode project using msvc2015

Debug/Release x86 configuration

Image

xxhash v0.8.2 kernel-mode project using msvc2015 Debug/Release x86 configuration ![Image](https://github.com/user-attachments/assets/8d9c2216-0699-4e55-bc5f-49827d9097ff)
Cyan4973 commented 2025-06-13 11:12:33 -05:00 (Migrated from github.com)
  1. msvc 2015 is relatively old at that point.
    Any way you could test with an updated version of msvc ?

  2. latest release is v0.8.3. please update, it may that this issue or a similar enough one was fixed since v0.8.2.

1) msvc 2015 is relatively old at that point. Any way you could test with an updated version of msvc ? 2) latest release is `v0.8.3`. please update, it _may_ that this issue or a similar enough one was fixed since v0.8.2.
t-mat commented 2025-06-14 04:33:19 -05:00 (Migrated from github.com)

Hi @iaoedsz2008,
It seems strange situation.

Since it's compiled as Release / x86 (indicated at the upper left corner of the screen shot), MSVC 2015 must define _M_IX86:

Visual Studio 2015: _M_IX86
Defined as the integer literal value 600 for compilations that target x86 processors.
This macro isn't defined for x64 or ARM compilation targets.

But it seems _M_IX86 is not defined for some reason.

Therefore, it skips line 4862 (_mm_load_si128) which is suitable for x86 target.

And reaches line 4864. But since _mm_set_epi64x is not declared, MSVC claims the error.

Please check the following intrinsics lists:

I think you should check your platform settings and predefined macros.

If you set x86 platform but MSVC 2015 doesn't define _M_IX86, it may mean something wrong in your build environment.


edit: We have some test for MSVC x86 (Win32)

https://github.com/Cyan4973/xxHash/actions/runs/15399523908/job/43328545697#step:5:22

and it's compiled and tested (hopefully) well. But it doesn't mean our code and test are perfect. So could you check your _MSC_VER and _M_IX86 ?

For example, compile and run the following code will display them. (It may not suitable for kernel mode code, but I think you can understand it).

#include <stdio.h>
int main() {
#if defined(_MSC_VER)
    printf("_MSC_VER=%d\n", _MSC_VER);
#else
    printf("_MSC_VER is not defined\n");
#endif
#if defined(_M_IX86)
    printf("_M_IX86 is defined\n");
#else
    printf("_M_IX86 is not defined\n");
#endif
}
Hi @iaoedsz2008, It seems strange situation. Since it's compiled as `Release / x86` (indicated at the upper left corner of the screen shot), MSVC 2015 must define [`_M_IX86`](https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-140): > Visual Studio 2015: `_M_IX86` > Defined as the integer literal value 600 for compilations that target x86 processors. > This macro isn't defined for x64 or ARM compilation targets. But it seems `_M_IX86` is not defined for some reason. Therefore, it skips line 4862 (`_mm_load_si128`) which is suitable for x86 target. And reaches line 4864. But since `_mm_set_epi64x` is not declared, MSVC claims the error. Please check the following intrinsics lists: - [MSVC 2015, x86 intrinsics](https://learn.microsoft.com/en-us/cpp/intrinsics/x86-intrinsics-list?view=msvc-140) : x86 doesn't contain `_mm_set_epi64x`. - [MSVC 2015, x64 intrinsics](https://learn.microsoft.com/en-us/cpp/intrinsics/x64-amd64-intrinsics-list?view=msvc-140) : x64 has `_mm_set_epi64x`. I think you should check your platform settings and predefined macros. If you set `x86` platform but MSVC 2015 doesn't define `_M_IX86`, it may mean something wrong in your build environment. --- edit: We have some test for MSVC x86 (Win32) https://github.com/Cyan4973/xxHash/actions/runs/15399523908/job/43328545697#step:5:22 and it's compiled and tested (hopefully) well. But it doesn't mean our code and test are perfect. So could you check your `_MSC_VER` and `_M_IX86` ? For example, compile and run the following code will display them. (It may not suitable for kernel mode code, but I think you can understand it). ``` #include <stdio.h> int main() { #if defined(_MSC_VER) printf("_MSC_VER=%d\n", _MSC_VER); #else printf("_MSC_VER is not defined\n"); #endif #if defined(_M_IX86) printf("_M_IX86 is defined\n"); #else printf("_M_IX86 is not defined\n"); #endif } ```
swiglu commented 2025-06-14 07:25:30 -05:00 (Migrated from github.com)

I've tested both in kernel mode and user mode, and found that the issue occurs at '_MSC_VER < 1900'. MSVC 2015 defines _MSC_VER as 1900, this should be changed to '_MSC_VER <= 1900'.

Image

Image

Also, the GitHub Actions link you shared uses MSVC 2019, not MSVC 2015.

I've tested both in kernel mode and user mode, and found that the issue occurs at '_MSC_VER < 1900'. MSVC 2015 defines _MSC_VER as 1900, this should be changed to '_MSC_VER <= 1900'. ![Image](https://github.com/user-attachments/assets/a3caa935-a3a5-4499-a944-56cbee43dd9e) ![Image](https://github.com/user-attachments/assets/211f9379-b666-4dbe-8b6a-3f92750c05f7) Also, the GitHub Actions link you shared uses MSVC 2019, not MSVC 2015.
Cyan4973 commented 2025-06-14 13:59:59 -05:00 (Migrated from github.com)

Github Actions does not offer MSVC 2015 runners, hence the difficulties to test such an old version in CI.

The source file used in your second example seems to be from a different project than xxhash, maybe for illustration.
An equivalent segment from xxhash.h would be :
https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h#L5276

#       if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900
        /* MSVC 32bit mode does not support _mm_set_epi64x before 2015 */
        XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, (xxh_i64)(0U - seed64) };
        __m128i const seed = _mm_load_si128((__m128i const*)seed64x2);
#       else
        __m128i const seed = _mm_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64);
#       endif

As stated by the comment,
it was expecting MSVC 2015 to support _mm_set_epi64x().
But apparently, according to your tests, it doesn't.
So that's a change of expectation.

The proposed change itself is fairly simple, so it would be simple to do.
We just need to be sure that it's the right thing to do.

Github Actions does not offer MSVC 2015 runners, hence the difficulties to test such an old version in CI. The source file used in your second example seems to be from a different project than `xxhash`, maybe for illustration. An equivalent segment from `xxhash.h` would be : https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h#L5276 ```C # if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900 /* MSVC 32bit mode does not support _mm_set_epi64x before 2015 */ XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, (xxh_i64)(0U - seed64) }; __m128i const seed = _mm_load_si128((__m128i const*)seed64x2); # else __m128i const seed = _mm_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64); # endif ``` As stated by the comment, it was expecting MSVC 2015 to support `_mm_set_epi64x()`. But apparently, according to your tests, it doesn't. So that's a change of expectation. The proposed change itself is fairly simple, so it would be simple to do. We just need to be sure that it's the right thing to do.
Cyan4973 commented 2025-06-14 14:59:29 -05:00 (Migrated from github.com)

Since MSVC 2015 is not available on Github Actions,
I created a new test on appveyor.ci, where it's still possible to launch MSVC 2015.

Using latest dev branch code,
the test successfully completed win32 + AVX2 build without any warning:

https://ci.appveyor.com/project/YannCollet/xxhash/builds/52238159/job/s54st2b6d35wihtk#L114

Hence, so far, the test did not reproduce the reported issue.

Since MSVC 2015 is not available on Github Actions, I created a new test on `appveyor.ci`, where it's still possible to launch MSVC 2015. Using latest `dev` branch code, the test successfully completed `win32` + `AVX2` build without any warning: https://ci.appveyor.com/project/YannCollet/xxhash/builds/52238159/job/s54st2b6d35wihtk#L114 Hence, so far, the test did not reproduce the reported issue.
swiglu commented 2025-06-14 23:38:35 -05:00 (Migrated from github.com)

After reviewing your test commands, I noticed the /arch:AVX2 flag. The current compilation error occurs in the XXH3_initCustomSecret_sse2 function, which remains unreferenced when AVX2 is enabled

After reviewing your test commands, I noticed the /arch:AVX2 flag. The current compilation error occurs in the XXH3_initCustomSecret_sse2 function, which remains unreferenced when AVX2 is enabled
Cyan4973 commented 2025-06-14 23:48:33 -05:00 (Migrated from github.com)

There are actually both build modes, with and without AVX2.
On x64, no-AVX2 implies SSE2.
But on win32, maybe not.

There are actually both build modes, with and without AVX2. On `x64`, no-AVX2 implies `SSE2`. But on `win32`, maybe not.
Cyan4973 commented 2025-06-15 00:00:11 -05:00 (Migrated from github.com)

Follow up:
I added a test that checks compilation with Visual Studio 2015 for a win32 build with SSE2 enabled :
https://ci.appveyor.com/project/YannCollet/xxhash/builds/52238428/job/m5jst49n2ax2d70p#L91

The build does not fail.

Follow up: I added a test that checks compilation with Visual Studio 2015 for a win32 build with SSE2 enabled : https://ci.appveyor.com/project/YannCollet/xxhash/builds/52238428/job/m5jst49n2ax2d70p#L91 The build does not fail.
t-mat commented 2025-06-15 02:25:45 -05:00 (Migrated from github.com)

It seems Microsoft's official x86 intrinsic table for MSVC 2022 is wrong. This table doesn't contain _mm_set_epi64x but actually MSVC 2022 supports it for x86.

Because %Program Files%/Microsoft Visual Studio/2022/.../MSVC/.../include/intrin.h contains the following line

// _mm_set_epi64x is enabled for x86 and x64
__MACHINEX86_X64(__m128i _mm_set_epi64x(__int64, __int64))
Details of MSVC 2022 intrinsic headers
// MSVC 2022
// %Program Files%/Microsoft Visual Studio/2022/.../MSVC/.../include/intrin0.inl.h

/*
** __MACHINEX86           : x86 only
** __MACHINEX64           : x64 only
** __MACHINEX86_X64       : x86 and x64 only
** __MACHINEZ             : nothing
*/

#define __MACHINEX86           __MACHINE
#define __MACHINEX64           __MACHINE
#define __MACHINEX86_X64       __MACHINE

#define __MACHINE(X)        X;
#define __MACHINEZ(X)       /* NOTHING */

// ...

// if _M_IX86 is not defined, disable __MACHINEX86
#if !defined(_M_IX86) || defined(_CHPE_ONLY_)
#undef __MACHINEX86
#define __MACHINEX86        __MACHINEZ
#endif

// if _M_X64 is not defined, disable __MACHINEX64
#if !defined(_M_X64) || defined(_M_ARM64EC)
#undef __MACHINEX64
#define __MACHINEX64        __MACHINEZ
#endif

// if _M_IX86 and _M_X64 are not defined, disable __MACHINEX86_X64
#if !(defined(_M_IX86) || defined(_M_X64)) || defined(_CHPE_ONLY_) || defined(_M_ARM64EC)
#undef __MACHINEX86_X64
#define __MACHINEX86_X64    __MACHINEZ
#endif

note that _CHPE_ONLY_ and _M_ARM64EC are symbols for Windows on ARM. So, we can ignore them for now.

// MSVC 2022
// %Program Files%/Microsoft Visual Studio/2022/.../MSVC/.../include/intrin.h
#include <intrin0.inl.h>

__MACHINEX86(__m128i _mm_set_epi64(__m64, __m64))            // x86 only
__MACHINEX86_X64(__m128i _mm_set_epi64x(__int64, __int64))   // x86 and x64

Hence as for MSVC2022, xxhash.h's code and comment are true.

Though we need to check actual intrinsic headers in MSVC2015. If it doesn't support _mm_set_epi64x for some reason, we should change our _MSC_VER check as @iaoedsz2008 proposed.

I'm downloading MSVC2015 .iso image from archive, but it's painfully slow 😢

It seems [Microsoft's official x86 intrinsic table for MSVC 2022](https://learn.microsoft.com/en-us/cpp/intrinsics/x86-intrinsics-list?view=msvc-170) is wrong. This table doesn't contain `_mm_set_epi64x` but actually MSVC 2022 supports it for x86. Because `%Program Files%/Microsoft Visual Studio/2022/.../MSVC/.../include/intrin.h` contains the following line ``` // _mm_set_epi64x is enabled for x86 and x64 __MACHINEX86_X64(__m128i _mm_set_epi64x(__int64, __int64)) ``` <details> <summary>Details of MSVC 2022 intrinsic headers</summary> ``` // MSVC 2022 // %Program Files%/Microsoft Visual Studio/2022/.../MSVC/.../include/intrin0.inl.h /* ** __MACHINEX86 : x86 only ** __MACHINEX64 : x64 only ** __MACHINEX86_X64 : x86 and x64 only ** __MACHINEZ : nothing */ #define __MACHINEX86 __MACHINE #define __MACHINEX64 __MACHINE #define __MACHINEX86_X64 __MACHINE #define __MACHINE(X) X; #define __MACHINEZ(X) /* NOTHING */ // ... // if _M_IX86 is not defined, disable __MACHINEX86 #if !defined(_M_IX86) || defined(_CHPE_ONLY_) #undef __MACHINEX86 #define __MACHINEX86 __MACHINEZ #endif // if _M_X64 is not defined, disable __MACHINEX64 #if !defined(_M_X64) || defined(_M_ARM64EC) #undef __MACHINEX64 #define __MACHINEX64 __MACHINEZ #endif // if _M_IX86 and _M_X64 are not defined, disable __MACHINEX86_X64 #if !(defined(_M_IX86) || defined(_M_X64)) || defined(_CHPE_ONLY_) || defined(_M_ARM64EC) #undef __MACHINEX86_X64 #define __MACHINEX86_X64 __MACHINEZ #endif ``` note that `_CHPE_ONLY_` and `_M_ARM64EC` are symbols for Windows on ARM. So, we can ignore them for now. ``` // MSVC 2022 // %Program Files%/Microsoft Visual Studio/2022/.../MSVC/.../include/intrin.h #include <intrin0.inl.h> __MACHINEX86(__m128i _mm_set_epi64(__m64, __m64)) // x86 only __MACHINEX86_X64(__m128i _mm_set_epi64x(__int64, __int64)) // x86 and x64 ``` </details> Hence as for MSVC2022, `xxhash.h`'s code and comment are true. Though we need to check actual intrinsic headers in MSVC2015. If it doesn't support `_mm_set_epi64x` for some reason, we should change our `_MSC_VER` check as @iaoedsz2008 proposed. I'm downloading MSVC2015 .iso image from archive, but it's painfully slow 😢
Cyan4973 commented 2025-06-15 02:28:54 -05:00 (Migrated from github.com)

The updated appveyor CI test list is now part of the dev branch,
it contains a MSVC 2015 + win32 + SSE2 build test :
https://ci.appveyor.com/project/YannCollet/xxhash/builds/52238702/job/9buegshf84fhg4no#L91

and it builds fine, not even a warning.

The updated appveyor CI test list is now part of the `dev` branch, it contains a MSVC 2015 + win32 + SSE2 build test : https://ci.appveyor.com/project/YannCollet/xxhash/builds/52238702/job/9buegshf84fhg4no#L91 and it builds fine, not even a warning.
swiglu commented 2025-06-15 04:07:23 -05:00 (Migrated from github.com)

I noticed that AVX2_ENABLED=true in the environment variables. However, in another job where it's set to false, the configuration uses MSVC 2013 instead.

https://ci.appveyor.com/project/YannCollet/xxhash/builds/52238702/job/9buegshf84fhg4no

Environment: COMPILER=visual, ARCHITECTURES=Win32,x64, AVX2_ENABLED=true, APPVEYOR_BUILD_WORKER_IMAGE=Visual Studio 2015, TEST_XXHSUM=true

https://ci.appveyor.com/project/YannCollet/xxhash/builds/52238702/job/xkmbnbgcgqsuqu49

Environment: COMPILER=visual, ARCHITECTURES=Win32,x64, AVX2_ENABLED=false, APPVEYOR_BUILD_WORKER_IMAGE=Visual Studio 2013, TEST_XXHSUM=true
I noticed that `AVX2_ENABLED=true` in the environment variables. However, in another job where it's set to false, the configuration uses MSVC 2013 instead. https://ci.appveyor.com/project/YannCollet/xxhash/builds/52238702/job/9buegshf84fhg4no ``` Environment: COMPILER=visual, ARCHITECTURES=Win32,x64, AVX2_ENABLED=true, APPVEYOR_BUILD_WORKER_IMAGE=Visual Studio 2015, TEST_XXHSUM=true ``` https://ci.appveyor.com/project/YannCollet/xxhash/builds/52238702/job/xkmbnbgcgqsuqu49 ``` Environment: COMPILER=visual, ARCHITECTURES=Win32,x64, AVX2_ENABLED=false, APPVEYOR_BUILD_WORKER_IMAGE=Visual Studio 2013, TEST_XXHSUM=true ```
swiglu commented 2025-06-15 06:34:15 -05:00 (Migrated from github.com)

After reviewing the AppVeyor logs again, I confirmed you were correct. I further investigated the issue locally and found that the kernel-mode header files are missing certain definitions.

Image

Image

After reviewing the AppVeyor logs again, I confirmed you were correct. I further investigated the issue locally and found that the kernel-mode header files are missing certain definitions. ![Image](https://github.com/user-attachments/assets/9d67f9a4-1599-4f04-b45f-23443aa9deaa) ![Image](https://github.com/user-attachments/assets/83f4e1ff-561e-4241-9bca-a641da48705a)
t-mat commented 2025-06-15 06:34:16 -05:00 (Migrated from github.com)

I've checked genuine MSVC 2015 Community Edition:

  • Visual Studio Community 2015: version 14.0.25431.01 Update 3
  • cl.exe: 19.00.24215.1 for x86

I set its target to x86. Compiled and run the following code:

#include <stdio.h>
#include <stdint.h>
#include <intrin.h>

int main() {
#if defined(_MSC_VER)
    printf("_MSC_VER=%d\n", _MSC_VER);
#else
    printf("_MSC_VER is not defined\n");
#endif
#if defined(_M_IX86)
    printf("_M_IX86 is defined\n");
#else
    printf("_M_IX86 is not defined\n");
#endif
    __m128i const x = _mm_set_epi64x(0x1234, 0x5678);
    alignas(16) uint8_t v[16];
    _mm_store_si128((__m128i*)v, x);
    printf("x = ");
    for (uint8_t u8 : v) {
        printf("%02x ", u8);
    }
    printf("\n");
}

MSVC 2015 doesn't report any error and warning. Its output is:

_MSC_VER=1900
_M_IX86 is defined
x = 78 56 00 00 00 00 00 00 34 12 00 00 00 00 00 00

Its intrin.h contains the following line:

__MACHINEX86_X64(__m128i _mm_set_epi64x(__int64, __int64))
Details of MSVC 2015 intrinsic header
// MSVC 2015
// %ProgramFiles(x86)%/Microsoft Visual Studio 14.0/VC/include/intrin.h 
#ifndef _M_CEE_PURE
    #if defined (_M_IX86) || defined (_M_X64)
        #include <immintrin.h>
        #include <ammintrin.h>
    #endif
    #if defined (_M_IX86)
        #include <mm3dnow.h>
    #endif
#endif

/*
** __MACHINE              : everything
** __MACHINEX86           : x86 only
** __MACHINEX64           : x64 only
** __MACHINEX86_X64       : x86 and x64 only
** __MACHINEZ             : nothing
*/
#define __MACHINEX86           __MACHINE
#define __MACHINEX64           __MACHINE
#define __MACHINEX86_X64       __MACHINE

#define __MACHINE(X)        X;
#define __MACHINEZ(X)       /* NOTHING */

#if !defined (_M_IX86)
#undef __MACHINEX86
#define __MACHINEX86        __MACHINEZ
#endif  /* !defined (_M_IX86) */

#if !defined (_M_X64)
#undef __MACHINEX64
#define __MACHINEX64        __MACHINEZ
#endif  /* !defined (_M_X64) */

#if !(defined (_M_IX86) || defined (_M_X64))
#undef __MACHINEX86_X64
#define __MACHINEX86_X64    __MACHINEZ
#endif  /* !(defined (_M_IX86) || defined (_M_X64)) */

__MACHINEX86(__m128i _mm_set_epi64(__m64, __m64))
__MACHINEX86_X64(__m128i _mm_set_epi64x(__int64, __int64))

Note that _M_CEE_PURE is deprecated symbol for /clr.

Therefore as for MSVC 2015, we can use _mm_set_epi64x() for both of x86 and x64 as @Cyan4973 and his new test proved.

@iaoedsz2008, please check your build environment and intrin.h again. So far, I don't find any issue in intrin.h and our code.

I've checked genuine MSVC 2015 Community Edition: - Visual Studio Community 2015: version 14.0.25431.01 Update 3 - cl.exe: 19.00.24215.1 for x86 I set its target to x86. Compiled and run the following code: ```C #include <stdio.h> #include <stdint.h> #include <intrin.h> int main() { #if defined(_MSC_VER) printf("_MSC_VER=%d\n", _MSC_VER); #else printf("_MSC_VER is not defined\n"); #endif #if defined(_M_IX86) printf("_M_IX86 is defined\n"); #else printf("_M_IX86 is not defined\n"); #endif __m128i const x = _mm_set_epi64x(0x1234, 0x5678); alignas(16) uint8_t v[16]; _mm_store_si128((__m128i*)v, x); printf("x = "); for (uint8_t u8 : v) { printf("%02x ", u8); } printf("\n"); } ``` MSVC 2015 doesn't report any error and warning. Its output is: ``` _MSC_VER=1900 _M_IX86 is defined x = 78 56 00 00 00 00 00 00 34 12 00 00 00 00 00 00 ``` Its `intrin.h` contains the following line: ``` __MACHINEX86_X64(__m128i _mm_set_epi64x(__int64, __int64)) ``` <details> <summary>Details of MSVC 2015 intrinsic header</summary> ``` // MSVC 2015 // %ProgramFiles(x86)%/Microsoft Visual Studio 14.0/VC/include/intrin.h #ifndef _M_CEE_PURE #if defined (_M_IX86) || defined (_M_X64) #include <immintrin.h> #include <ammintrin.h> #endif #if defined (_M_IX86) #include <mm3dnow.h> #endif #endif /* ** __MACHINE : everything ** __MACHINEX86 : x86 only ** __MACHINEX64 : x64 only ** __MACHINEX86_X64 : x86 and x64 only ** __MACHINEZ : nothing */ #define __MACHINEX86 __MACHINE #define __MACHINEX64 __MACHINE #define __MACHINEX86_X64 __MACHINE #define __MACHINE(X) X; #define __MACHINEZ(X) /* NOTHING */ #if !defined (_M_IX86) #undef __MACHINEX86 #define __MACHINEX86 __MACHINEZ #endif /* !defined (_M_IX86) */ #if !defined (_M_X64) #undef __MACHINEX64 #define __MACHINEX64 __MACHINEZ #endif /* !defined (_M_X64) */ #if !(defined (_M_IX86) || defined (_M_X64)) #undef __MACHINEX86_X64 #define __MACHINEX86_X64 __MACHINEZ #endif /* !(defined (_M_IX86) || defined (_M_X64)) */ __MACHINEX86(__m128i _mm_set_epi64(__m64, __m64)) __MACHINEX86_X64(__m128i _mm_set_epi64x(__int64, __int64)) ``` Note that `_M_CEE_PURE` is deprecated symbol for [/clr](https://learn.microsoft.com/en-us/cpp/build/reference/clr-common-language-runtime-compilation?view=msvc-170). </details> Therefore as for MSVC 2015, we can use `_mm_set_epi64x()` for both of x86 and x64 as @Cyan4973 and his new test proved. @iaoedsz2008, please check your build environment and `intrin.h` again. So far, I don't find any issue in `intrin.h` and our code.
swiglu commented 2025-06-15 06:38:52 -05:00 (Migrated from github.com)

I've checked genuine MSVC 2015 Community Edition:

  • Visual Studio Community 2015: version 14.0.25431.01 Update 3
  • cl.exe: 19.00.24215.1 for x86

I set its target to x86. Compiled and run the following code:

#include <stdio.h>
#include <stdint.h>
#include <intrin.h>

int main() {
#if defined(_MSC_VER)
printf("_MSC_VER=%d\n", _MSC_VER);
#else
printf("_MSC_VER is not defined\n");
#endif
#if defined(_M_IX86)
printf("_M_IX86 is defined\n");
#else
printf("_M_IX86 is not defined\n");
#endif
__m128i const x = _mm_set_epi64x(0x1234, 0x5678);
alignas(16) uint8_t v[16];
_mm_store_si128((__m128i*)v, x);
printf("x = ");
for (uint8_t u8 : v) {
printf("%02x ", u8);
}
printf("\n");
}
MSVC 2015 doesn't report any error and warning. Its output is:

_MSC_VER=1900
_M_IX86 is defined
x = 78 56 00 00 00 00 00 00 34 12 00 00 00 00 00 00

Its intrin.h contains the following line:

__MACHINEX86_X64(__m128i _mm_set_epi64x(__int64, __int64))

Details of MSVC 2015 intrinsic header
Therefore as for MSVC 2015, we can use _mm_set_epi64x() for both of x86 and x64 as @Cyan4973 and his new test proved.

@iaoedsz2008, please check your build environment and intrin.h again. So far, I don't find any issue in intrin.h and our code.

We replied almost simultaneously - please check my comments above.

files:
"C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\km\crt\emmintrin.h"
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\emmintrin.h"

> I've checked genuine MSVC 2015 Community Edition: > > * Visual Studio Community 2015: version 14.0.25431.01 Update 3 > * cl.exe: 19.00.24215.1 for x86 > > I set its target to x86. Compiled and run the following code: > > #include <stdio.h> > #include <stdint.h> > #include <intrin.h> > > int main() { > #if defined(_MSC_VER) > printf("_MSC_VER=%d\n", _MSC_VER); > #else > printf("_MSC_VER is not defined\n"); > #endif > #if defined(_M_IX86) > printf("_M_IX86 is defined\n"); > #else > printf("_M_IX86 is not defined\n"); > #endif > __m128i const x = _mm_set_epi64x(0x1234, 0x5678); > alignas(16) uint8_t v[16]; > _mm_store_si128((__m128i*)v, x); > printf("x = "); > for (uint8_t u8 : v) { > printf("%02x ", u8); > } > printf("\n"); > } > MSVC 2015 doesn't report any error and warning. Its output is: > > ``` > _MSC_VER=1900 > _M_IX86 is defined > x = 78 56 00 00 00 00 00 00 34 12 00 00 00 00 00 00 > ``` > > Its `intrin.h` contains the following line: > > ``` > __MACHINEX86_X64(__m128i _mm_set_epi64x(__int64, __int64)) > ``` > > Details of MSVC 2015 intrinsic header > Therefore as for MSVC 2015, we can use `_mm_set_epi64x()` for both of x86 and x64 as [@Cyan4973](https://github.com/Cyan4973) and his new test proved. > > [@iaoedsz2008](https://github.com/iaoedsz2008), please check your build environment and `intrin.h` again. So far, I don't find any issue in `intrin.h` and our code. We replied almost simultaneously - please check my comments above. files: "C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\km\crt\emmintrin.h" "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\emmintrin.h"
t-mat commented 2025-06-15 06:40:43 -05:00 (Migrated from github.com)

@iaoedsz2008, great find!

So we need special clause for MSVC 2015 + kernel mode compilation (older Windows Driver Kit header).

@iaoedsz2008, great find! So we need special clause for MSVC 2015 + kernel mode compilation (older Windows Driver Kit header).
t-mat commented 2025-06-15 07:08:39 -05:00 (Migrated from github.com)

1000% off-topic but I'm surprised Microsoft still supports Visual Studio 2015 officially for enterprise customers.

Image

1000% off-topic but I'm surprised [Microsoft still supports Visual Studio 2015](https://learn.microsoft.com/en-us/lifecycle/products/visual-studio-2015) officially for enterprise customers. ![Image](https://github.com/user-attachments/assets/9e86f8bf-089f-4704-8ed4-efd197f1d3d4)
t-mat commented 2025-06-15 10:42:42 -05:00 (Migrated from github.com)

I've succeeded to reproduce _mm_set_epi64x() issue with Microsoft Enterprise WDK for Visual Studio 2015 - EnterpriseWDK_rs1_release_14393_20160715-1616.

  • Download EnterpriseWDK_rs1_release_14393_20160715-1616.zip
  • Extract the zip file.
  • Open new terminal.
  • cd to above extracted directory.
  • Copy my test code (last part of this post) as main.cpp
  • Input the following commands:
cmd.exe
.\LaunchBuildEnv.cmd

where cl.exe
: ...\EnterpriseWDK_rs1_release_14393_20160715-1616\Program Files\Microsoft Visual Studio 14.0\VC\bin\cl.exe

cl.exe
: Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24210 for x86

cl.exe main.cpp /I ".\Program Files\Windows Kits\10\Include\10.0.14393.0\km\crt" /I ".\Program Files\Windows Kits\10\Include\10.0.14393.0\shared" /link /LIBPATH:".\Program Files\Microsoft Visual Studio 14.0\VC\lib" /LIBPATH:".\Program Files\Windows Kits\10\Lib\10.0.14393.0\um\x86" /LIBPATH:".\Program Files\Windows Kits\10\Lib\10.0.14393.0\ucrt\x86"
: main.cpp(16): error C3861: '_mm_set_epi64x': identifier not found

ug.exe "_mm_set_epi64" ".\Program Files\Windows Kits\10\Include\10.0.14393.0\km\crt\emmintrin.h"
:   338: extern __m128i _mm_set_epi64(__m64 _Q1, __m64 _Q0);

If we enable the // Workaround line, main.exe's exitcode is 20 as expected.

.\main.exe
echo %errorlevel%
: 20
: == (0x12 + 0x34 + 0x56 + 0x78) & 255 == 20

main.cpp

#include <intrin.h>

int main() {
#if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900
//#if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER <= 1900 // Workaround
    alignas(16) const unsigned long long u64x2[2] = { 0x1234, 0x5678 };
    __m128i const x = _mm_load_si128((__m128i const*) u64x2);
#else
    __m128i const x = _mm_set_epi64x(0x1234, 0x5678);
#endif
    alignas(16) unsigned char v[16];
    _mm_store_si128((__m128i*)v, x);

    int r = 0;
    for (auto const e : v) {
        r += e;
    }
    return (r & 255);
}
I've succeeded to reproduce `_mm_set_epi64x()` issue with [Microsoft Enterprise WDK](https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk#download-icon-for-ewdk-enterprise-wdk-ewdk) for [Visual Studio 2015 - `EnterpriseWDK_rs1_release_14393_20160715-1616`](https://learn.microsoft.com/en-us/legal/windows/hardware/enterprise-wdk-license-2015). - Download `EnterpriseWDK_rs1_release_14393_20160715-1616.zip` - Extract the zip file. - Open new terminal. - `cd` to above extracted directory. - Copy my test code (last part of this post) as `main.cpp` - Input the following commands: ```bat cmd.exe .\LaunchBuildEnv.cmd where cl.exe : ...\EnterpriseWDK_rs1_release_14393_20160715-1616\Program Files\Microsoft Visual Studio 14.0\VC\bin\cl.exe cl.exe : Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24210 for x86 cl.exe main.cpp /I ".\Program Files\Windows Kits\10\Include\10.0.14393.0\km\crt" /I ".\Program Files\Windows Kits\10\Include\10.0.14393.0\shared" /link /LIBPATH:".\Program Files\Microsoft Visual Studio 14.0\VC\lib" /LIBPATH:".\Program Files\Windows Kits\10\Lib\10.0.14393.0\um\x86" /LIBPATH:".\Program Files\Windows Kits\10\Lib\10.0.14393.0\ucrt\x86" : main.cpp(16): error C3861: '_mm_set_epi64x': identifier not found ug.exe "_mm_set_epi64" ".\Program Files\Windows Kits\10\Include\10.0.14393.0\km\crt\emmintrin.h" : 338: extern __m128i _mm_set_epi64(__m64 _Q1, __m64 _Q0); ``` If we enable the `// Workaround` line, `main.exe`'s exitcode is `20` as expected. ```bat .\main.exe echo %errorlevel% : 20 : == (0x12 + 0x34 + 0x56 + 0x78) & 255 == 20 ``` ### main.cpp ```C #include <intrin.h> int main() { #if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900 //#if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER <= 1900 // Workaround alignas(16) const unsigned long long u64x2[2] = { 0x1234, 0x5678 }; __m128i const x = _mm_load_si128((__m128i const*) u64x2); #else __m128i const x = _mm_set_epi64x(0x1234, 0x5678); #endif alignas(16) unsigned char v[16]; _mm_store_si128((__m128i*)v, x); int r = 0; for (auto const e : v) { r += e; } return (r & 255); } ```
swiglu commented 2025-06-15 12:42:03 -05:00 (Migrated from github.com)

Wow, thank you for taking the time to reproduce this issue!

Wow, thank you for taking the time to reproduce this issue!
Cyan4973 commented 2025-06-15 13:14:35 -05:00 (Migrated from github.com)

Great investigation @t-mat !

In conclusion, it implies that the proposed fix is to disable _mm_set_epi64x() for all versions of MSVC 2015 because one of them doesn't ship this symbol?

It feels like a pity, but on the other hand, I don't think it matters so much, and it's likely preferable to reduce noise.

Great investigation @t-mat ! In conclusion, it implies that the proposed fix is to disable `_mm_set_epi64x()` for all versions of `MSVC 2015` because one of them doesn't ship this symbol? It feels like a pity, but on the other hand, I don't think it matters so much, and it's likely preferable to reduce noise.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-Cyan4973/xxHash#1042
No description provided.