From 11b599f8f98639f38dd59aebf764fc2700abae5e Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Tue, 18 Jun 2019 09:34:55 -0700 Subject: [PATCH 1/3] 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) { From fa4dfffd8ec55f5629b994327c7a06af4ddd8ab1 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Tue, 18 Jun 2019 09:53:54 -0700 Subject: [PATCH 2/3] Update reverb SIMD to avoid benign UBSan warnings due to unaligned load/store --- libraries/audio/src/AudioReverb.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libraries/audio/src/AudioReverb.cpp b/libraries/audio/src/AudioReverb.cpp index a7c6fefd39..4d89172a38 100644 --- a/libraries/audio/src/AudioReverb.cpp +++ b/libraries/audio/src/AudioReverb.cpp @@ -1796,6 +1796,18 @@ void AudioReverb::render(float** inputs, float** outputs, int numFrames) { #include +// 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 AudioReverb::convertInput(const int16_t* input, float** outputs, int numFrames) { __m128 scale = _mm_set1_ps(1/32768.0f); @@ -1816,7 +1828,7 @@ void AudioReverb::convertInput(const int16_t* input, float** outputs, int numFra _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 @@ -1887,7 +1899,7 @@ void AudioReverb::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); } } From ce7571dcc13cfb3156c4c77449d4668b8971d3fe Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Tue, 18 Jun 2019 10:29:23 -0700 Subject: [PATCH 3/3] Replace NEXTPOW2() macros with constexpr (supported since VS2015) --- libraries/audio/src/AudioReverb.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/libraries/audio/src/AudioReverb.cpp b/libraries/audio/src/AudioReverb.cpp index 4d89172a38..26f5528866 100644 --- a/libraries/audio/src/AudioReverb.cpp +++ b/libraries/audio/src/AudioReverb.cpp @@ -35,16 +35,6 @@ static const double SQRT2 = 1.41421356237309504880; static const double FIXQ31 = 2147483648.0; static const double FIXQ32 = 4294967296.0; -// Round an integer to the next power-of-two, at compile time. -// VS2013 does not support constexpr so macros are used instead. -#define SETBITS0(x) (x) -#define SETBITS1(x) (SETBITS0(x) | (SETBITS0(x) >> 1)) -#define SETBITS2(x) (SETBITS1(x) | (SETBITS1(x) >> 2)) -#define SETBITS3(x) (SETBITS2(x) | (SETBITS2(x) >> 4)) -#define SETBITS4(x) (SETBITS3(x) | (SETBITS3(x) >> 8)) -#define SETBITS5(x) (SETBITS4(x) | (SETBITS4(x) >> 16)) -#define NEXTPOW2(x) (SETBITS5((x) - 1) + 1) - // // Allpass delay modulation // @@ -111,6 +101,18 @@ static const int M_AP19 = 113; static const int M_AP20 = 107; static const int M_AP21 = 127; +// Round an integer to the next power-of-two, at compile time +constexpr uint32_t NEXTPOW2(uint32_t n) { + n -= 1; + n |= (n >> 1); + n |= (n >> 2); + n |= (n >> 4); + n |= (n >> 8); + n |= (n >> 16); + n += 1; + return n; +} + // // Filter design tools using analog-matched response. // All filter types approximate the s-plane response, including cutoff > Nyquist.