Fix unaligned read/write in lpf_vertical_4_neon Address of src buffer can only be 2-bytes aligned. Hence replacing the operations by unaligned load/store functions. BUG=aomedia:2186 Change-Id: Id56bbc1ff8ba533652c2668cbf4f4356a95d8495
diff --git a/aom_dsp/arm/loopfilter_neon.c b/aom_dsp/arm/loopfilter_neon.c index bdc6762..aafac89 100644 --- a/aom_dsp/arm/loopfilter_neon.c +++ b/aom_dsp/arm/loopfilter_neon.c
@@ -785,16 +785,15 @@ const uint8_t *limit, const uint8_t *thresh) { uint32x2x2_t p1q0_p0q1, p1q1_p0q0, p1p0_q1q0; uint32x2_t pq_rev; - uint8x8_t UNINITIALIZED_IS_SAFE(p1p0), q0q1, p0q0, p1q1; + uint8x8_t UNINITIALIZED_IS_SAFE(p1p0), UNINITIALIZED_IS_SAFE(q0q1); + uint8x8_t p0q0, p1q1; // row0: p1 p0 | q0 q1 // row1: p1 p0 | q0 q1 // row2: p1 p0 | q0 q1 // row3: p1 p0 | q0 q1 - load_u8_4x1(src - 2, &p1p0, 0); - load_u8_4x1((src - 2) + 1 * stride, &p1p0, 1); - load_u8_4x1((src - 2) + 2 * stride, &q0q1, 0); - load_u8_4x1((src - 2) + 3 * stride, &q0q1, 1); + load_unaligned_u8_4x4(src - 2, stride, (uint32x2_t *)&p1p0, + (uint32x2_t *)&q0q1); transpose_u8_4x4(&p1p0, &q0q1); @@ -815,10 +814,10 @@ transpose_u8_4x4(&p1p0, &q0q1); - store_u8_4x1(src - 2, p1p0, 0); - store_u8_4x1((src - 2) + 1 * stride, q0q1, 0); - store_u8_4x1((src - 2) + 2 * stride, p1p0, 1); - store_u8_4x1((src - 2) + 3 * stride, q0q1, 1); + store_unaligned_u8_4x1(src - 2, p1p0, 0); + store_unaligned_u8_4x1((src - 2) + 1 * stride, q0q1, 0); + store_unaligned_u8_4x1((src - 2) + 2 * stride, p1p0, 1); + store_unaligned_u8_4x1((src - 2) + 3 * stride, q0q1, 1); } void aom_lpf_horizontal_14_neon(uint8_t *src, int stride, const uint8_t *blimit,
diff --git a/av1/common/arm/mem_neon.h b/av1/common/arm/mem_neon.h index c4ae2e7..beae4ed 100644 --- a/av1/common/arm/mem_neon.h +++ b/av1/common/arm/mem_neon.h
@@ -383,6 +383,15 @@ *tu0 = vset_lane_u32(a, *tu0, 1); } +/* These intrinsics require immediate values, so we must use #defines + to enforce that. */ +#define store_unaligned_u8_4x1(dst, src, lane) \ + do { \ + uint32_t a; \ + a = vget_lane_u32(vreinterpret_u32_u8(src), lane); \ + memcpy(dst, &a, 4); \ + } while (0) + static INLINE void load_unaligned_u8_2x2(const uint8_t *buf, int stride, uint16x4_t *tu0) { uint16_t a;