Handle Arm/AArch64 runtime feature detection
authorWan-Teh Chang <wtc@google.com>
Sat, 7 Oct 2023 14:06:36 +0000 (07:06 -0700)
committerWan-Teh Chang <wtc@google.com>
Tue, 10 Oct 2023 16:27:20 +0000 (09:27 -0700)
Port the following libaom CLs to libvpx:
https://aomedia-review.googlesource.com/c/aom/+/178361
https://aomedia-review.googlesource.com/c/aom/+/180701
https://aomedia-review.googlesource.com/c/aom/+/181821

The tests themselves are not feature-gated in the same way that they are
used in the rest of the codebase since they are not controlled by
rtcd.pl. This means that tests that assume the existence of features not
present on the target can cause SIGILL to be thrown.

This commit extends init_vpx_test.cc to match the behaviour for other
targets and automatically disable testing for features that are not
available on the machine running the tests.

Call arm_cpu_caps() and x86_simd_caps() inside #if !CONFIG_SHARED.
All the SIMD-specialized functions (arm or x86) are internal functions,
so they are not exported from the libvpx shared library. If
CONFIG_SHARED is 1, it is not necessary to call arm_cpu_caps(),
x86_simd_caps(), and append_negative_gtest_filter() either.

Change-Id: I330631816bdb52842020c5aa2a1ad802865cc285

test/init_vpx_test.cc

index 5b40d9e..e88c54f 100644 (file)
 
 #include "test/init_vpx_test.h"
 
+#include "./vpx_config.h"
+
+#if !CONFIG_SHARED
 #include <string>
 #include "third_party/googletest/src/include/gtest/gtest.h"
-#include "./vpx_config.h"
+#if VPX_ARCH_ARM
+#include "vpx_ports/arm.h"
+#endif
 #if VPX_ARCH_X86 || VPX_ARCH_X86_64
 #include "vpx_ports/x86.h"
 #endif
@@ -27,7 +32,7 @@ extern void vpx_dsp_rtcd();
 extern void vpx_scale_rtcd();
 }
 
-#if VPX_ARCH_X86 || VPX_ARCH_X86_64
+#if VPX_ARCH_ARM || VPX_ARCH_X86 || VPX_ARCH_X86_64
 static void append_negative_gtest_filter(const char *str) {
   std::string filter = GTEST_FLAG_GET(filter);
   // Negative patterns begin with one '-' followed by a ':' separated list.
@@ -35,10 +40,25 @@ static void append_negative_gtest_filter(const char *str) {
   filter += str;
   GTEST_FLAG_SET(filter, filter);
 }
-#endif  // VPX_ARCH_X86 || VPX_ARCH_X86_64
+#endif  // VPX_ARCH_ARM || VPX_ARCH_X86 || VPX_ARCH_X86_64
+#endif  // !CONFIG_SHARED
 
 namespace libvpx_test {
 void init_vpx_test() {
+#if !CONFIG_SHARED
+#if VPX_ARCH_AARCH64
+  const int caps = arm_cpu_caps();
+  if (!(caps & HAS_NEON_DOTPROD)) {
+    append_negative_gtest_filter(":NEON_DOTPROD.*:NEON_DOTPROD/*");
+  }
+  if (!(caps & HAS_NEON_I8MM)) {
+    append_negative_gtest_filter(":NEON_I8MM.*:NEON_I8MM/*");
+  }
+#elif VPX_ARCH_ARM
+  const int caps = arm_cpu_caps();
+  if (!(caps & HAS_NEON)) append_negative_gtest_filter(":NEON.*:NEON/*");
+#endif  // VPX_ARCH_ARM
+
 #if VPX_ARCH_X86 || VPX_ARCH_X86_64
   const int simd_caps = x86_simd_caps();
   if (!(simd_caps & HAS_MMX)) append_negative_gtest_filter(":MMX.*:MMX/*");
@@ -58,9 +78,8 @@ void init_vpx_test() {
   }
 #endif  // VPX_ARCH_X86 || VPX_ARCH_X86_64
 
-#if !CONFIG_SHARED
-// Shared library builds don't support whitebox tests
-// that exercise internal symbols.
+  // Shared library builds don't support whitebox tests that exercise internal
+  // symbols.
 #if CONFIG_VP8
   vp8_rtcd();
 #endif  // CONFIG_VP8