Update the hardware CRC32 logic in scudo to support using -mcrc32
instead of -msse4.2. The CRC32 intrinsics use the former flag
in the newer compiler versions, e.g. in clang since 12fa608af44a.
With these versions of clang, passing -msse4.2 is insufficient
to enable the instructions and causes build failures when -march does
not enable CRC32 implicitly:
/var/tmp/portage/sys-libs/compiler-rt-sanitizers-14.0.0/work/compiler-rt/lib/scudo/scudo_crc32.cpp:20:10: error: always_inline function '_mm_crc32_u32' requires target feature 'crc32', but would be inlined into function 'computeHardwareCRC32' that is compiled without support for 'crc32' return CRC32_INTRINSIC(Crc, Data); ^ /var/tmp/portage/sys-libs/compiler-rt-sanitizers-14.0.0/work/compiler-rt/lib/scudo/scudo_crc32.h:27:27: note: expanded from macro 'CRC32_INTRINSIC' # define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64) ^ /var/tmp/portage/sys-libs/compiler-rt-sanitizers-14.0.0/work/compiler-rt/lib/scudo/../sanitizer_common/sanitizer_platform.h:132:36: note: expanded from macro 'FIRST_32_SECOND_64' # define FIRST_32_SECOND_64(a, b) (a) ^ 1 error generated.
For backwards compatibility, use -mcrc32 when available and fall back
to -msse4.2. The <smmintrin.h> header remains in use as it still
works and is compatible with GCC, while clang's <crc32intrin.h>
is not.
Use builtin_ia32*() rather than _mm_crc32*() when using -mcrc32
to preserve compatibility with GCC. _mm_crc32*() are aliases
to builtin_ia32*() in both compilers but GCC requires -msse4.2
for the former, while both use -mcrc32 for the latter.
Originally reported in https://bugs.gentoo.org/835870.