sample-code/hwcaps-test.c (44 lines of code) (raw):

#include <stdio.h> #include <sys/auxv.h> #include <asm/hwcap.h> #include <arm_sve.h> #define sizeof_array(a) (sizeof(a) / sizeof((a)[0])) uint64_t sum_all(uint32_t *values, int length) { uint64_t sum = 0; for (int i = 0; i < length; i++) sum += values[i]; return sum; } #pragma GCC target("+sve2") #pragma clang attribute push(__attribute__((target("sve2"))), apply_to = function) uint64_t sum_all_sve2(uint32_t *values, int length) { svuint64_t sum = svdup_u64(0); int i = 0; svbool_t predicate = svwhilelt_b32(i, length); do { svuint32_t a = svld1(predicate, (uint32_t *) &values[i]); sum = svadalp_u64_x(predicate, sum, a); i += svcntw(); predicate = svwhilelt_b32(i, length); } while (svptest_any(svptrue_b32(), predicate)); return svaddv_u64(svptrue_b64(), sum); } #pragma clang attribute pop void test() { uint32_t values[13] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; int have_sve = !!(getauxval(AT_HWCAP2) & HWCAP2_SVE2); uint64_t sum = 0; if (have_sve) { sum = sum_all_sve(&values[0], sizeof_array(values)); } else { sum = sum_all(&values[0], sizeof_array(values)); } printf("sum: %lu, computed %s SVE2\n", sum, (have_sve) ? "with" : "without"); } int main(int argc, char *argv[]) { test(); return 0; }