Skip to content

Commit 6697c5b

Browse files
mgornytstellar
authored andcommitted
[compiler-rt] [scudo] Use -mcrc32 on x86 when available
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 12fa608. 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. Differential Revision: https://reviews.llvm.org/D122789 (cherry picked from commit fd1da78)
1 parent 8475349 commit 6697c5b

File tree

9 files changed

+33
-18
lines changed

9 files changed

+33
-18
lines changed

compiler-rt/cmake/config-ix.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ check_cxx_compiler_flag(-fno-profile-generate COMPILER_RT_HAS_FNO_PROFILE_GENERA
7878
check_cxx_compiler_flag(-fno-profile-instr-generate COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG)
7979
check_cxx_compiler_flag(-fno-profile-instr-use COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG)
8080
check_cxx_compiler_flag(-fno-coverage-mapping COMPILER_RT_HAS_FNO_COVERAGE_MAPPING_FLAG)
81+
check_cxx_compiler_flag("-Werror -mcrc32" COMPILER_RT_HAS_MCRC32_FLAG)
8182
check_cxx_compiler_flag("-Werror -msse3" COMPILER_RT_HAS_MSSE3_FLAG)
8283
check_cxx_compiler_flag("-Werror -msse4.2" COMPILER_RT_HAS_MSSE4_2_FLAG)
8384
check_cxx_compiler_flag(--sysroot=. COMPILER_RT_HAS_SYSROOT_FLAG)

compiler-rt/lib/scudo/CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,11 @@ set(SCUDO_HEADERS
8686
scudo_tsd_shared.inc
8787
scudo_utils.h)
8888

89-
# Enable the SSE 4.2 instruction set for scudo_crc32.cpp, if available.
90-
if (COMPILER_RT_HAS_MSSE4_2_FLAG)
89+
# Enable the necessary instruction set for scudo_crc32.cpp, if available.
90+
# Newer compiler versions use -mcrc32 rather than -msse4.2.
91+
if (COMPILER_RT_HAS_MCRC32_FLAG)
92+
set_source_files_properties(scudo_crc32.cpp PROPERTIES COMPILE_FLAGS -mcrc32)
93+
elseif (COMPILER_RT_HAS_MSSE4_2_FLAG)
9194
set_source_files_properties(scudo_crc32.cpp PROPERTIES COMPILE_FLAGS -msse4.2)
9295
endif()
9396

compiler-rt/lib/scudo/scudo_allocator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ inline u32 computeCRC32(u32 Crc, uptr Value, uptr *Array, uptr ArraySize) {
4949
// as opposed to only for scudo_crc32.cpp. This means that other hardware
5050
// specific instructions were likely emitted at other places, and as a
5151
// result there is no reason to not use it here.
52-
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
52+
#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
5353
Crc = CRC32_INTRINSIC(Crc, Value);
5454
for (uptr i = 0; i < ArraySize; i++)
5555
Crc = CRC32_INTRINSIC(Crc, Array[i]);
@@ -65,7 +65,7 @@ inline u32 computeCRC32(u32 Crc, uptr Value, uptr *Array, uptr ArraySize) {
6565
for (uptr i = 0; i < ArraySize; i++)
6666
Crc = computeSoftwareCRC32(Crc, Array[i]);
6767
return Crc;
68-
#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
68+
#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
6969
}
7070

7171
static BackendT &getBackend();

compiler-rt/lib/scudo/scudo_crc32.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515

1616
namespace __scudo {
1717

18-
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
18+
#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
1919
u32 computeHardwareCRC32(u32 Crc, uptr Data) {
2020
return CRC32_INTRINSIC(Crc, Data);
2121
}
22-
#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
22+
#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
2323

2424
} // namespace __scudo

compiler-rt/lib/scudo/scudo_crc32.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,25 @@
1616
#include "sanitizer_common/sanitizer_internal_defs.h"
1717

1818
// Hardware CRC32 is supported at compilation via the following:
19-
// - for i386 & x86_64: -msse4.2
19+
// - for i386 & x86_64: -mcrc32 (earlier: -msse4.2)
2020
// - for ARM & AArch64: -march=armv8-a+crc or -mcrc
2121
// An additional check must be performed at runtime as well to make sure the
2222
// emitted instructions are valid on the target host.
2323

24-
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
25-
# ifdef __SSE4_2__
24+
#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
25+
# if defined(__CRC32__)
26+
// NB: clang has <crc32intrin.h> but GCC does not
27+
# include <smmintrin.h>
28+
# define CRC32_INTRINSIC FIRST_32_SECOND_64(__builtin_ia32_crc32si, __builtin_ia32_crc32di)
29+
# elif defined(__SSE4_2__)
2630
# include <smmintrin.h>
2731
# define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64)
2832
# endif
2933
# ifdef __ARM_FEATURE_CRC32
3034
# include <arm_acle.h>
3135
# define CRC32_INTRINSIC FIRST_32_SECOND_64(__crc32cw, __crc32cd)
3236
# endif
33-
#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
37+
#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
3438

3539
namespace __scudo {
3640

compiler-rt/lib/scudo/standalone/CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,11 @@ set(SCUDO_SOURCES
9797
string_utils.cpp
9898
)
9999

100-
# Enable the SSE 4.2 instruction set for crc32_hw.cpp, if available.
101-
if (COMPILER_RT_HAS_MSSE4_2_FLAG)
100+
# Enable the necessary instruction set for scudo_crc32.cpp, if available.
101+
# Newer compiler versions use -mcrc32 rather than -msse4.2.
102+
if (COMPILER_RT_HAS_MCRC32_FLAG)
103+
set_source_files_properties(crc32_hw.cpp PROPERTIES COMPILE_FLAGS -mcrc32)
104+
elseif (COMPILER_RT_HAS_MSSE4_2_FLAG)
102105
set_source_files_properties(crc32_hw.cpp PROPERTIES COMPILE_FLAGS -msse4.2)
103106
endif()
104107

compiler-rt/lib/scudo/standalone/checksum.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@
1212
#include "internal_defs.h"
1313

1414
// Hardware CRC32 is supported at compilation via the following:
15-
// - for i386 & x86_64: -msse4.2
15+
// - for i386 & x86_64: -mcrc32 (earlier: -msse4.2)
1616
// - for ARM & AArch64: -march=armv8-a+crc or -mcrc
1717
// An additional check must be performed at runtime as well to make sure the
1818
// emitted instructions are valid on the target host.
1919

20-
#ifdef __SSE4_2__
20+
#if defined(__CRC32__)
21+
// NB: clang has <crc32intrin.h> but GCC does not
22+
#include <smmintrin.h>
23+
#define CRC32_INTRINSIC FIRST_32_SECOND_64(__builtin_ia32_crc32si, __builtin_ia32_crc32di)
24+
#elif defined(__SSE4_2__)
2125
#include <smmintrin.h>
2226
#define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64)
2327
#endif

compiler-rt/lib/scudo/standalone/chunk.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ inline u16 computeChecksum(u32 Seed, uptr Value, uptr *Array, uptr ArraySize) {
2525
// as opposed to only for crc32_hw.cpp. This means that other hardware
2626
// specific instructions were likely emitted at other places, and as a result
2727
// there is no reason to not use it here.
28-
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
28+
#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
2929
u32 Crc = static_cast<u32>(CRC32_INTRINSIC(Seed, Value));
3030
for (uptr I = 0; I < ArraySize; I++)
3131
Crc = static_cast<u32>(CRC32_INTRINSIC(Crc, Array[I]));
@@ -42,7 +42,7 @@ inline u16 computeChecksum(u32 Seed, uptr Value, uptr *Array, uptr ArraySize) {
4242
Checksum = computeBSDChecksum(Checksum, Array[I]);
4343
return Checksum;
4444
}
45-
#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
45+
#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
4646
}
4747

4848
namespace Chunk {

compiler-rt/lib/scudo/standalone/crc32_hw.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010

1111
namespace scudo {
1212

13-
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
13+
#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
1414
u32 computeHardwareCRC32(u32 Crc, uptr Data) {
1515
return static_cast<u32>(CRC32_INTRINSIC(Crc, Data));
1616
}
17-
#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
17+
#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
1818

1919
} // namespace scudo

0 commit comments

Comments
 (0)