From 11b599f8f98639f38dd59aebf764fc2700abae5e Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Tue, 18 Jun 2019 09:34:55 -0700 Subject: [PATCH] Update SIMD resampler to avoid benign UBSan warnings due to unaligned load/store --- libraries/audio/src/AudioSRC.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/libraries/audio/src/AudioSRC.cpp b/libraries/audio/src/AudioSRC.cpp index d488eccb6a..625f45e9ae 100644 --- a/libraries/audio/src/AudioSRC.cpp +++ b/libraries/audio/src/AudioSRC.cpp @@ -793,6 +793,18 @@ int AudioSRC::multirateFilter4(const float* input0, const float* input1, const f #include // SSE2 +// unaligned load/store without undefined behavior +static inline __m128i mm_loadu_si32(void const* mem_addr) { + int32_t temp; + memcpy(&temp, mem_addr, sizeof(int32_t)); + return _mm_cvtsi32_si128(temp); +} + +static inline void mm_storeu_si32(void* mem_addr, __m128i a) { + int32_t temp = _mm_cvtsi128_si32(a); + memcpy(mem_addr, &temp, sizeof(int32_t)); +} + // convert int16_t to float, deinterleave stereo void AudioSRC::convertInput(const int16_t* input, float** outputs, int numFrames) { __m128 scale = _mm_set1_ps(1/32768.0f); @@ -839,7 +851,7 @@ void AudioSRC::convertInput(const int16_t* input, float** outputs, int numFrames _mm_storeu_ps(&outputs[1][i], f1); } for (; i < numFrames; i++) { - __m128i a0 = _mm_cvtsi32_si128(*(int32_t*)&input[2*i]); + __m128i a0 = mm_loadu_si32((__m128i*)&input[2*i]); __m128i a1 = a0; // deinterleave and sign-extend @@ -878,9 +890,9 @@ void AudioSRC::convertInput(const int16_t* input, float** outputs, int numFrames _mm_storeu_ps(&outputs[3][i], _mm_shuffle_ps(f1, f3, _MM_SHUFFLE(3,1,3,1))); } for (; i < numFrames; i++) { - __m128i a0 = _mm_cvtsi32_si128(*(int32_t*)&input[4*i+0]); + __m128i a0 = mm_loadu_si32((__m128i*)&input[4*i+0]); __m128i a1 = a0; - __m128i a2 = _mm_cvtsi32_si128(*(int32_t*)&input[4*i+2]); + __m128i a2 = mm_loadu_si32((__m128i*)&input[4*i+2]); __m128i a3 = a2; // deinterleave and sign-extend @@ -986,7 +998,7 @@ void AudioSRC::convertOutput(float** inputs, int16_t* output, int numFrames) { // interleave a0 = _mm_unpacklo_epi16(a0, a1); - *(int32_t*)&output[2*i] = _mm_cvtsi128_si32(a0); + mm_storeu_si32((__m128i*)&output[2*i], a0); } } else if (_numChannels == 4) {