SDL: * Support for intrinsics in MSW + Clang scenario.

From 50db4a59b85f1895493cd0bad676ebb208ee8e82 Mon Sep 17 00:00:00 2001
From: Vladislav Dmitrievich Turbanov <[EMAIL REDACTED]>
Date: Fri, 2 Apr 2021 12:05:45 +0300
Subject: [PATCH] * Support for intrinsics in MSW + Clang scenario. Utility
 polyfill is provided, removed the no-longer-needed conditionals.

---
 CMakeLists.txt        | 11 +++++------
 include/SDL_cpuinfo.h | 23 ++++++++++++++++-------
 include/SDL_endian.h  | 18 +++++++++++++++++-
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b78accc85..0cdab8cff 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -778,11 +778,6 @@ if(ASSEMBLY)
     set(HAVE_SSE3 TRUE)
     set(SDL_ASSEMBLY_ROUTINES 1)
   endif()
-# TODO:
-#else()
-#  if(USE_GCC OR USE_CLANG)
-#    list(APPEND EXTRA_CFLAGS "-mno-sse" "-mno-sse2" "-mno-sse3" "-mno-mmx")
-#  endif()
 endif()
 
 # TODO: Can't deactivate on FreeBSD? w/o LIBC, SDL_stdinc.h can't define
@@ -2526,7 +2521,11 @@ if (ASAN)
   asan_check_add_debug_flag("undefined")
   asan_check_add_debug_flag("vla-bound")
   asan_check_add_debug_flag("leak")
-  asan_check_add_debug_flag("object-size")
+  # The object size sanitizer has no effect on unoptimized builds on Clang,
+  # but causes warnings.
+  if((NOT USE_CLANG) OR (CMAKE_BUILD_TYPE STREQUAL ""))
+    asan_check_add_debug_flag("object-size")
+  endif()
 endif()
 
 ##### Tests #####
diff --git a/include/SDL_cpuinfo.h b/include/SDL_cpuinfo.h
index d5273113c..9c4c193ad 100644
--- a/include/SDL_cpuinfo.h
+++ b/include/SDL_cpuinfo.h
@@ -34,11 +34,20 @@
 /* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */
 #if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64))
 #ifdef __clang__
-/* Many of the intrinsics SDL uses are not implemented by clang with Visual Studio */
-#undef __MMX__
-#undef __SSE__
-#undef __SSE2__
-#else
+/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
+   so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
+
+#ifndef __PRFCHWINTRIN_H
+#define __PRFCHWINTRIN_H
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_m_prefetch(void *__P)
+{
+  __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */);
+}
+
+#endif /* __PRFCHWINTRIN_H */
+#endif /* __clang__ */
 #include <intrin.h>
 #ifndef _WIN64
 #ifndef __MMX__
@@ -54,7 +63,6 @@
 #ifndef __SSE2__
 #define __SSE2__
 #endif
-#endif /* __clang__ */
 #elif defined(__MINGW64_VERSION_MAJOR)
 #include <intrin.h>
 #if !defined(SDL_DISABLE_ARM_NEON_H) && defined(__ARM_NEON)
@@ -82,6 +90,8 @@
 #    endif
 #  endif
 #endif
+#endif /* compiler version */
+
 #if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H)
 #include <mm3dnow.h>
 #endif
@@ -101,7 +111,6 @@
 #include <pmmintrin.h>
 #endif
 #endif /* HAVE_IMMINTRIN_H */
-#endif /* compiler version */
 
 #include "begin_code.h"
 /* Set up for C function definitions, even when using C++ */
diff --git a/include/SDL_endian.h b/include/SDL_endian.h
index ae78be4d6..0a8e204a4 100644
--- a/include/SDL_endian.h
+++ b/include/SDL_endian.h
@@ -30,7 +30,23 @@
 
 #include "SDL_stdinc.h"
 
-#if defined(_MSC_VER) && !defined(__clang__)
+#ifdef _MSC_VER
+/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
+   so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
+
+#ifdef __clang__
+#ifndef __PRFCHWINTRIN_H
+#define __PRFCHWINTRIN_H
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_m_prefetch(void *__P)
+{
+  __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */);
+}
+
+#endif /* __PRFCHWINTRIN_H */
+#endif /* __clang__ */
+
 #include <intrin.h>
 #endif