diff --git a/storage/innobase/ut/ut0crc32.cc b/storage/innobase/ut/ut0crc32.cc
index 80a0d165069..0f7efb8b5b7 100644
--- a/storage/innobase/ut/ut0crc32.cc
+++ b/storage/innobase/ut/ut0crc32.cc
@@ -86,8 +86,17 @@ mysys/my_perf.c, contributed by Facebook under the following license.
 #include "ut0crc32.h"
 #include "my_valgrind.h"
 
-#ifdef _MSC_VER
-# include <intrin.h>
+#ifdef HAVE_CPUID_INSTRUCTION
+# ifdef _MSC_VER
+#  include <intrin.h>
+# elif defined __GNUC__ && !defined __clang__ && __GNUC__ < 5
+/* <nmmintrin.h> does not really work in GCC before version 5 */
+#  define _mm_crc32_u8(crc,data) __builtin_ia32_crc32qi(crc,data)
+#  define _mm_crc32_u32(crc,data) __builtin_ia32_crc32si(crc,data)
+#  define _mm_crc32_u64(crc,data) __builtin_ia32_crc32di(crc,data)
+# else
+#  include <nmmintrin.h>
+# endif
 #endif
 
 /* CRC32 hardware implementation. */
@@ -123,43 +132,25 @@ static inline bool has_sse4_2()
 @param crc   CRC-32C checksum so far
 @param data  data to be checksummed
 @return the updated CRC-32C */
+__attribute__((target("sse4.2")))
 static inline ulint ut_crc32c_8(ulint crc, byte data)
 {
-#  ifdef _MSC_VER
   return _mm_crc32_u8(static_cast<uint32_t>(crc), data);
-#  elif __has_feature(memory_sanitizer)
-  return __builtin_ia32_crc32qi(static_cast<uint32_t>(crc), data);
-#  else
-  asm("crc32b %1, %0" : "+r" (crc) : "rm" (data));
-  return crc;
-#  endif
 }
 
 /** Append 64 bits (8 aligned bytes) to a CRC-32C checksum
 @param[in] crc    CRC-32C checksum so far
 @param[in] data   8 bytes of aligned data
 @return the updated CRC-32C */
+__attribute__((target("sse4.2")))
 static inline ulint ut_crc32c_64(ulint crc, uint64_t data)
 {
-#  ifdef _MSC_VER
-#   ifdef _M_X64
+#  if SIZEOF_SIZE_T > 4
   return _mm_crc32_u64(crc, data);
-#   elif defined(_M_IX86)
+#  else
   crc= _mm_crc32_u32(crc, static_cast<uint32_t>(data));
   crc= _mm_crc32_u32(crc, static_cast<uint32_t>(data >> 32));
   return crc;
-#   else
-#    error Unsupported processor type
-#   endif
-#  elif __has_feature(memory_sanitizer)
-  return __builtin_ia32_crc32di(crc, data);
-#  elif defined __x86_64__
-  asm("crc32q %1, %0" : "+r" (crc) : "rm" (data));
-  return crc;
-#  else
-  asm("crc32l %1, %0" : "+r" (crc) : "rm" (static_cast<uint32_t>(data)));
-  asm("crc32l %1, %0" : "+r" (crc) : "rm" (static_cast<uint32_t>(data >> 32)));
-  return crc;
 #  endif
 }