Max
Max

Reputation: 16719

Errors when compiling NEON code on Android

Here is simple binarization function

void binarize(void *output, const void *input, int begin, int end, uint8_t threshold) {
#ifdef __ARM_NEON__
    uint8x16_t thresholdVector = vdupq_n_u8(threshold);
    uint8x16_t highValueVector = vdupq_n_u8(255);
    uint8x16_t* __restrict inputVector = (uint8x16_t*)input;
    uint8x16_t* __restrict outputVector = (uint8x16_t*)output;
    for ( ; begin < end; begin += 16, ++inputVector, ++outputVector) {
        *outputVector = (*inputVector > thresholdVector) & highValueVector;
    }
#endif
}

It works fine on iOS. However when I'm compiling it for Android it gives me an error:

error: invalid operands of types 'uint8x16_t {aka __vector(16) __builtin_neon_uqi}' and 'uint8x16_t {aka __vector(16) __builtin_neon_uqi}' to binary 'operator>'

I use this flag in Android.mk to enable NEON:

ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
      LOCAL_ARM_NEON := true
endif

Upvotes: 2

Views: 479

Answers (1)

Andrey Kamaev
Andrey Kamaev

Reputation: 30122

The difference comes because of different compilers. For iOS you are compiling with Clang but for Android you are building the code with GCC (unless you override the defaults).

GCC is much more stupid about vector types and could not use them with C/C++ operators like > or &. So you have two basic options:

  1. Try to compile with Clang from the latest Android NDK r8c

    Put NDK_TOOLCHAIN_VERSION=clang3.1 to your Application.mk for this.

  2. Rewrite your code explicitly using vld1q_u8 for load, vst1q_u8 for store, vcgtq_u8 for operator > and vandq_u8 for operator &

Upvotes: 3

Related Questions