diff options
author | Timothy B. Terriberry <tterribe@xiph.org> | 2022-07-02 12:14:06 -0700 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@amazon.com> | 2022-07-05 17:25:54 -0400 |
commit | e535e894196387b12d9fcbc271a98b21572a630b (patch) | |
tree | deb470aa9b0e1251cad18183484ec754d8e13aa4 | |
parent | 7b6cede819a673cc21e896283668b2d3ddd9e623 (diff) | |
download | opus-e535e894196387b12d9fcbc271a98b21572a630b.tar.gz |
Work around UBSan unaligned access errors.
The underlying objects are all 8-bit integers.
Verified that the generated assembly still just uses MOVD.
Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
-rw-r--r-- | celt/x86/x86cpu.h | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/celt/x86/x86cpu.h b/celt/x86/x86cpu.h index 0de8df35..04e80489 100644 --- a/celt/x86/x86cpu.h +++ b/celt/x86/x86cpu.h @@ -56,8 +56,16 @@ int opus_select_arch(void); # endif +/*MOVD should not impose any alignment restrictions, but the C standard does, + and UBSan will report errors if we actually make unaligned accesses. + Use this to work around those restrictions (which should hopefully all get + optimized to a single MOVD instruction).*/ +#define OP_LOADU_EPI32(x) \ + (int)((*(unsigned char *)(x) | *((unsigned char *)(x) + 1) << 8U |\ + *((unsigned char *)(x) + 2) << 16U | (opus_uint32)*((unsigned char *)(x) + 3) << 24U)) + #define OP_CVTEPI8_EPI32_M32(x) \ - (_mm_cvtepi8_epi32(_mm_cvtsi32_si128(*(int *)(x)))) + (_mm_cvtepi8_epi32(_mm_cvtsi32_si128(OP_LOADU_EPI32(x)))) #define OP_CVTEPI16_EPI32_M64(x) \ (_mm_cvtepi16_epi32(_mm_loadl_epi64((__m128i *)(x)))) |