diff mbox series

[07/10] aarch64: Add testcase for C/C++ ops on SVE ACLE types.

Message ID 20241106114613.2972987-8-tejas.belagod@arm.com
State New
Headers show
Series aarch64: Enable C/C++ operations on SVE ACLE types. | expand

Commit Message

Tejas Belagod Nov. 6, 2024, 11:46 a.m. UTC
This patch adds a test case to cover C/C++ operators on SVE ACLE types.  This
does not cover all types, but covers most representative types.

gcc/testsuite:

	* gcc.target/aarch64/sve/acle/general/cops.c: New test.
---
 .../aarch64/sve/acle/general/cops.c           | 570 ++++++++++++++++++
 1 file changed, 570 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops.c

Comments

Richard Sandiford Nov. 7, 2024, 11:22 a.m. UTC | #1
Tejas Belagod <tejas.belagod@arm.com> writes:
> This patch adds a test case to cover C/C++ operators on SVE ACLE types.  This
> does not cover all types, but covers most representative types.
>
> gcc/testsuite:
>
> 	* gcc.target/aarch64/sve/acle/general/cops.c: New test.
> ---
>  .../aarch64/sve/acle/general/cops.c           | 570 ++++++++++++++++++
>  1 file changed, 570 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops.c
>
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops.c
> new file mode 100644
> index 00000000000..28da602301e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops.c
> @@ -0,0 +1,570 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O2" } */
> +
> +#include <arm_sve.h>
> +#include <stdio.h>
> +
> +#define DECL_FUNC_UNARY(type, name, op, intr, su, sz, id) \
> +  __attribute__ ((noipa)) \
> +  type func_ ## name ## type ## _unary (type a) { \
> +    return op (a); \
> +  } \
> +  void checkfunc_ ## name ## type ## _unary () { \
> +    type data = svindex_ ## su ## sz (0, 1); \
> +    type zr = svindex_ ## su ## sz (0, 0); \
> +    type one = svindex_ ## su ## sz (1, 0); \
> +    type mone = svindex_ ## su ## sz (-1, 0); \
> +    svbool_t pg = svptrue_b ## sz (); \
> +    type exp = intr ## su ## sz ## _z (pg, id, data); \
> +    type actual = func_ ## name ## type ## _unary (data); \
> +    svbool_t res = svcmpeq_ ## su ## sz (pg, exp, actual); \
> +    if (svptest_any (pg, svnot_b_z (pg, res))) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_UNARY_FLOAT(type, name, op, intr, su, sz, id) \
> +  __attribute__ ((noipa)) \
> +  type func_ ## name ## type ## _unary (type a) { \
> +    return op (a); \
> +  } \
> +  void checkfunc_ ## name ## type ## _unary () { \
> +    type data = svdup_n_ ## su ## sz (2.0); \
> +    type zr = svdup_n_ ## su ## sz (0.0); \
> +    type one = svdup_n_ ## su ## sz (1.0); \
> +    type mone = svdup_n_ ## su ## sz (-1.0); \
> +    svbool_t pg = svptrue_b ## sz (); \
> +    type exp = intr ## su ## sz ## _z (pg, id, data); \
> +    type actual = func_ ## name ## type ## _unary (data); \
> +    svbool_t res = svcmpeq_ ## su ## sz (pg, exp, actual); \
> +    if (svptest_any (pg, svnot_b_z (pg, res))) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_INDEX(rtype, type, intr, su, sz)  \
> +  __attribute__ ((noipa)) \
> +  rtype func_ ## rtype ## type ## _vindex (type a, int n) { \
> +    return (a[n]); \
> +  } \
> +  __attribute__ ((noipa)) \
> +  rtype func_ ## rtype ## type ## _cindex (type a) { \
> +    return (a[0]); \
> +  } \
> +  void checkfunc_ ## rtype ## type ## _vindex () { \
> +    type a = svindex_ ## su ## sz (0, 1); \
> +    int n = 2; \
> +    if (2 != func_ ## rtype ## type ## _vindex (a, n)) \
> +      __builtin_abort (); \
> +  } \
> +  void checkfunc_ ## rtype ## type ## _cindex () { \
> +    type a = svindex_ ## su ## sz (1, 0); \
> +    if (1 != func_ ## rtype ## type ## _cindex (a)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_INDEX_FLOAT(rtype, type, intr, su, sz)  \
> +  __attribute__ ((noipa)) \
> +  rtype func_ ## rtype ## type ## _vindex (type a, int n) { \
> +    return (a[n]); \
> +  } \
> +  __attribute__ ((noipa)) \
> +  rtype func_ ## rtype ## type ## _cindex (type a) { \
> +    return (a[0]); \
> +  } \
> +  void checkfunc_ ## rtype ## type ## _vindex () { \
> +    type a = svdup_n_ ## su ## sz (2.0); \
> +    int n = 2; \
> +    if (2.0 != func_ ## rtype ## type ## _vindex (a, n)) \
> +      __builtin_abort (); \
> +  } \
> +  void checkfunc_ ## rtype ## type ## _cindex () { \
> +    type a = svdup_n_ ## su ## sz (4.0); \
> +    if (4.0 != func_ ## rtype ## type ## _cindex (a)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_BINARY(type, name, op, intr, su, sz)  \
> +  __attribute__ ((noipa)) \
> +  type func_ ## name  ## type ## _binary(type a, type b) { \
> +    return (a) op (b); \
> +  } \
> +  void checkfunc_ ## name ## type ## _binary () { \
> +    type a = svindex_ ## su ## sz (0, 1); \
> +    type b = svindex_ ## su ## sz (0, 2); \
> +    svbool_t all_true = svptrue_b ## sz (); \
> +    type exp = intr ## su ## sz ## _z (all_true, a, b); \
> +    type actual = func_ ## name ## type ## _binary (a, b); \
> +    svbool_t res = svcmpeq_ ## su ## sz (all_true, exp, actual); \
> +    if (svptest_any (all_true, svnot_b_z (all_true, res))) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_BINARY_SHIFT(type, name, op, intr, su, sz)  \
> +  __attribute__ ((noipa)) \
> +  type func_ ## name  ## type ## _binary(type a, type b) { \
> +    return (a) op (b); \
> +  } \
> +  void checkfunc_ ## name ## type ## _binary () { \
> +    type a = svindex_ ## su ## sz (0, 1); \
> +    svuint ## sz ## _t b = svindex_u ## sz (0, 2); \
> +    type c = svindex_ ## su ## sz (0, 2); \
> +    svbool_t all_true = svptrue_b ## sz (); \
> +    type exp = intr ## su ## sz ## _z (all_true, a, b); \
> +    type actual = func_ ## name ## type ## _binary (a, c); \
> +    svbool_t res = svcmpeq_ ## su ## sz (all_true, exp, actual); \
> +    if (svptest_any (all_true, svnot_b_z (all_true, res))) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_BINARY_FLOAT(type, name, op, intr, su, sz)  \
> +  __attribute__ ((noipa)) \
> +  type func_ ## name  ## type ## _binary(type a, type b) { \
> +    return (a) op (b); \
> +  } \
> +  void checkfunc_ ## name ## type ## _binary () { \
> +    type a = svdup_n_ ## su ## sz (1.0); \
> +    type b = svdup_n_ ## su ## sz (2.0); \
> +    svbool_t all_true = svptrue_b ## sz (); \
> +    type exp = intr ## su ## sz ## _z (all_true, a, b); \
> +    type actual = func_ ## name ## type ## _binary (a, b); \
> +    svbool_t res = svcmpeq_ ## su ## sz (all_true, exp, actual); \
> +    if (svptest_any (all_true, svnot_b_z (all_true, res))) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_BINARY_CMP(type, name, op, intr, su, sz)  \
> +  __attribute__ ((noipa)) \
> +  type func_ ## name  ## type ## _binary_cmp(type a, type b) { \
> +    return (a) op (b); \
> +  } \
> +  void checkfunc_ ## name ## type ## _binary_cmp () { \
> +    type a = svindex_ ## su ## sz (0, 1); \
> +    type b = svindex_ ## su ## sz (0, 2); \
> +    type c = func_ ## name ## type ## _binary_cmp (a, b); \
> +    svbool_t all_true = svptrue_b ## sz (); \
> +    svbool_t pgc = svcmpne_n_ ## su ## sz (all_true, c, 0); \
> +    svbool_t pg = intr ## su ## sz (all_true, a, b); \
> +    svbool_t res = sveor_b_z (all_true, pgc, pg); \
> +    if (svptest_any (all_true, res)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_TERNARY(type, su, sz) \
> +  __attribute__ ((noipa)) \
> +  type func_ ## type ## _ternary(type p, type q, type a, type b) { \
> +    return (p >= q) ? a : b; \
> +  } \
> +  void checkfunc_ ## type ## _ternary() { \
> +    type p = svindex_ ## su ## sz (0, 1); \
> +    type q = svindex_ ## su ## sz (1, 1); \
> +    type a = svindex_ ## su ## sz (2, 1); \
> +    type b = svindex_ ## su ## sz (3, 1); \
> +    svbool_t all_true = svptrue_b ## sz (); \
> +    svbool_t cmp = svcmpge_ ## su ## sz (all_true, p, q); \
> +    type res = svsel_ ## su ## sz (cmp, a, b); \
> +    type actual = func_ ## type ## _ternary(p, q, a, b); \
> +    svbool_t pgc = svcmpeq_ ## su ## sz (all_true, res, actual); \
> +    if (svptest_any (all_true, svnot_b_z (all_true, pgc))) \
> +      __builtin_abort (); \
> +  }
> +
> +#define VECT_CST_s8  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
> +#define VECT_CST_s16 { 0, 1, 2, 3, 4, 5, 6, 7 }
> +#define VECT_CST_s32 { 0, 1, 2, 3 }
> +#define VECT_CST_s64 { 0, 1 }
> +
> +#define DECL_FUNC_INIT(type, su, sz, nelem) \
> +  __attribute__ ((noipa)) \
> +  type func_ ## type ## _init1() { \
> +    type temp = VECT_CST_ ## su ## sz; \
> +    return temp; \
> +  } \
> +  __attribute__ ((noipa)) \
> +  type func_ ## type ## _init2() { \
> +    type temp = { 0 }; \
> +    return temp; \
> +  } \
> +  __attribute__ ((noipa)) \
> +  type func_ ## type ## _init3() { \
> +    type temp = { }; \
> +    return temp; \
> +  } \
> +  __attribute__ ((noipa)) \
> +  type func_ ## type ## _init4() { \
> +    type temp = VECT_CST_ ## su ## sz; \
> +    return temp; \
> +  } \

It looks like init4 repeats init1.  Is that intentional?

Otherwise it looks good, although the macros are a challenge :)

Thanks,
Richard

> +  void checkfunc_ ## type ## _init() { \
> +    svbool_t all_true = svptrue_b ## sz (); \
> +    int ## sz ## _t mem[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; \
> +    svbool_t cmp ## sz = svptrue_pat_b ## sz (SV_VL ## nelem); \
> +    type init1 = svld1_ ## su ## sz (cmp ## sz, mem); \
> +    type init2 = svindex_ ## su ## sz (0, 0); \
> +    type init3 = svindex_ ## su ## sz (0, 0); \
> +    type init4 = svld1_ ## su ## sz (cmp ## sz, mem); \
> +	\
> +    type res_init1 = func_ ## type ## _init1 (); \
> +    svbool_t cmp = svcmpne_ ## su ## sz (all_true, init1, res_init1); \
> +    if (svptest_any (all_true, cmp)) \
> +      __builtin_abort (); \
> +	\
> +    type res_init2 = func_ ## type ## _init2 (); \
> +    cmp = svcmpne_ ## su ## sz (all_true, init2, res_init2); \
> +    if (svptest_any (all_true, cmp)) \
> +      __builtin_abort (); \
> +	\
> +    type res_init3 = func_ ## type ## _init3 (); \
> +    cmp = svcmpne_ ## su ## sz (all_true, init3, res_init3); \
> +    if (svptest_any (all_true, cmp)) \
> +      __builtin_abort (); \
> +	\
> +    type res_init4 = func_ ## type ## _init4 (); \
> +    cmp = svcmpne_ ## su ## sz (all_true, init4, res_init4); \
> +    if (svptest_any (all_true, cmp)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_TERNARY_FLOAT(type, su, sz) \
> +  __attribute__ ((noipa)) \
> +  type func_ ## type ## _ternary(type p, type q, type a, type b) { \
> +    return (p >= q) ? a : b; \
> +  } \
> +  void checkfunc_ ## type ## _ternary() { \
> +    type p = svdup_n_ ## su ## sz (2.0); \
> +    type q = svdup_n_ ## su ## sz (1.0); \
> +    type a = svdup_n_ ## su ## sz (3.0); \
> +    type b = svdup_n_ ## su ## sz (4.0); \
> +    svbool_t all_true = svptrue_b ## sz (); \
> +    svbool_t cmp = svcmpge_ ## su ## sz (all_true, p, q); \
> +    type res = svsel_ ## su ## sz (cmp, a, b); \
> +    type actual = func_ ## type ## _ternary(p, q, a, b); \
> +    svbool_t pgc = svcmpeq_ ## su ## sz (all_true, res, actual); \
> +    if (svptest_any (all_true, svnot_b_z (all_true, pgc))) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_BINARY_SCALAR(scalar, type, name, op, intr, su, sz)  \
> +  __attribute__ ((noipa)) \
> +  type func_ ## name  ## type ## _binary_cscalar(type a) { \
> +    return (a) op scalar; \
> +  } \
> +  __attribute__ ((noipa)) \
> +  type func_ ## name  ## type ## _binary_vscalar(type a, int b) { \
> +    return (a) op b; \
> +  } \
> +  void checkfunc_ ## name ## type ## _binary_cscalar () { \
> +    type a = svindex_ ## su ## sz (0, 1); \
> +    svbool_t pg = svptrue_b ## sz (); \
> +    type exp = intr ## su ## sz ## _z (pg, a, scalar); \
> +    type actual = func_ ## name ## type ## _binary_cscalar (a); \
> +    svbool_t res = svcmpeq_ ## su ## sz (pg, exp, actual); \
> +    if (svptest_any (pg, svnot_b_z (pg, res))) \
> +      __builtin_abort (); \
> +  } \
> +  void checkfunc_ ## name ## type ## _binary_vscalar () { \
> +    type a = svindex_ ## su ## sz (0, 1); \
> +    svbool_t pg = svptrue_b ## sz (); \
> +    uint ## sz ## _t b = scalar; \
> +    type exp = intr ## su ## sz ## _z (pg, a, b); \
> +    type actual = func_ ## name ## type ## _binary_vscalar (a, b); \
> +    svbool_t res = svcmpeq_ ## su ## sz (pg, exp, actual); \
> +    if (svptest_any (pg, svnot_b_z (pg, res))) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_UNARY_RET_FLOAT(rtype, type, name, op, intr, su, sz)  \
> +  __attribute__ ((noipa)) \
> +  rtype func_ ## name  ## rtype ## type ## _unary(type a) { \
> +    return op (a); \
> +  } \
> +  void checkfunc_ ## name ## rtype ## type ## _unary () { \
> +    type a = svdup_n_ ## su ## sz (2.0); \
> +    svbool_t pg = svptrue_b ## sz (); \
> +    rtype exp = intr ## su ## sz ## _z (a); \
> +    rtype actual = func_ ## name ## type ## _unary (a); \
> +    svbool_t res = svcmpeq_ ## su ## sz (pg, exp, actual); \
> +    if (svptest_any (pg, svnot_b_z (pg, res))) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_BINARY_RET_FLOAT_CMP(rtype, type, name, op, intr, su, sz)  \
> +  __attribute__ ((noipa)) \
> +  rtype func_ ## name  ## rtype ## type ## _binary_cmp(type a, type b) { \
> +    return (a) op (b); \
> +  } \
> +  void checkfunc_ ## name ## rtype ## type ## _binary_cmp () { \
> +    type a = svdup_n_ ## su ## sz (2.0); \
> +    type b = svdup_n_ ## su ## sz (3.0); \
> +    svbool_t all_true = svptrue_b ## sz (); \
> +    rtype cmp = func_ ## name ## rtype ## type ## _binary_cmp (a, b); \
> +    svbool_t pgc = intr ## su ## sz (all_true, a, b) ; \
> +    svbool_t pg = svcmpne_n_s ## sz (all_true, cmp, 0); \
> +    svbool_t res = sveor_b_z (all_true, pg, pgc); \
> +    if (svptest_any (all_true, res)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_BINARY_RET_COND(rtype, type, name, op, intr, su, sz)  \
> +  __attribute__ ((noipa)) \
> +  rtype func_ ## name  ## rtype ## type ## _binary_cond(type a, type b) { \
> +    return (a) op (b); \
> +  } \
> +  __attribute__ ((noipa)) \
> +  svbool_t name ## intr ## su ## sz (svbool_t t, type a, type b) { \
> +    svbool_t pgl = svcmpne_n_ ## su ## sz (t, a, 0); \
> +    svbool_t pgr = svcmpne_n_ ## su ## sz (t, b, 0); \
> +    return intr ## b_z (t, pgl, pgr); \
> +  } \
> +  void checkfunc_ ## name ## rtype ## type ## _binary_cond () { \
> +    type a = svdup_n_ ## su ## sz (2); \
> +    type b = svdup_n_ ## su ## sz (3); \
> +    svbool_t all_true = svptrue_b ## sz (); \
> +    rtype cmp = func_ ## name ## rtype ## type ## _binary_cond (a, b); \
> +    svbool_t pgc = name ## intr ## su ## sz (all_true, a, b) ; \
> +    svbool_t pg = svcmpne_n_s ## sz (all_true, cmp, 0); \
> +    svbool_t res = sveor_b_z (all_true, pg, pgc); \
> +    if (svptest_any (all_true, res)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_UNARY_RET_COND(rtype, type, name, op, intr, su, sz)  \
> +  __attribute__ ((noipa)) \
> +  rtype func_ ## name  ## rtype ## type ## _unary_cond (type a) { \
> +    return op (a); \
> +  } \
> +  __attribute__ ((noipa)) \
> +  svbool_t name ## intr ## su ## sz (svbool_t t, type a) { \
> +    svbool_t pgl = svcmpeq_n_ ## su ## sz (t, a, 0); \
> +    return pgl; \
> +  } \
> +  void checkfunc_ ## name ## rtype ## type ## _unary_cond () { \
> +    type a = svdup_n_ ## su ## sz (2); \
> +    svbool_t all_true = svptrue_b ## sz (); \
> +    rtype cmp = func_ ## name ## rtype ## type ## _unary_cond (a); \
> +    svbool_t pgc = name ## intr ## su ## sz (all_true, a) ; \
> +    svbool_t pg = svcmpne_n_s ## sz (all_true, cmp, 0); \
> +    svbool_t res = sveor_b_z (all_true, pg, pgc); \
> +    if (svptest_any (all_true, res)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define TYPES_UNARY(name, op, intr, id) \
> +  DECL_FUNC_UNARY (svint8_t, name, op, intr, s, 8, id) \
> +  DECL_FUNC_UNARY (svint16_t, name, op, intr, s, 16, id) \
> +  DECL_FUNC_UNARY (svint32_t, name, op, intr, s, 32, id) \
> +  DECL_FUNC_UNARY (svint64_t, name, op, intr, s, 64, id) \
> +  DECL_FUNC_UNARY_FLOAT (svfloat32_t, name, op, intr, f, 32, id) \
> +  DECL_FUNC_UNARY_FLOAT (svfloat64_t, name, op, intr, f, 64, id)
> +
> +#define TYPES_INT_UNARY(name, op, intr, id) \
> +  DECL_FUNC_UNARY (svint8_t, name, op, intr, s, 8, id) \
> +  DECL_FUNC_UNARY (svint16_t, name, op, intr, s, 16, id) \
> +  DECL_FUNC_UNARY (svint32_t, name, op, intr, s, 32, id) \
> +  DECL_FUNC_UNARY (svint64_t, name, op, intr, s, 64, id)
> +
> +#define TYPES_BINARY(name, op, intr) \
> +  DECL_FUNC_BINARY (svint8_t, name, op, intr, s, 8) \
> +  DECL_FUNC_BINARY (svint16_t, name, op, intr, s, 16) \
> +  DECL_FUNC_BINARY (svint32_t, name, op, intr, s, 32) \
> +  DECL_FUNC_BINARY (svint64_t, name, op, intr, s, 64) \
> +  DECL_FUNC_BINARY_FLOAT (svfloat32_t, name, op, intr, f, 32) \
> +  DECL_FUNC_BINARY_FLOAT (svfloat64_t, name, op, intr, f, 64)
> +
> +#define TYPES_BINARY32_64(name, op, intr) \
> +  DECL_FUNC_BINARY (svint32_t, name, op, intr, s, 32) \
> +  DECL_FUNC_BINARY (svint64_t, name, op, intr, s, 64)
> +
> +#define TYPES_TERNARY() \
> +  DECL_FUNC_TERNARY (svint8_t, s, 8) \
> +  DECL_FUNC_TERNARY (svint16_t, s, 16) \
> +  DECL_FUNC_TERNARY (svint32_t, s, 32) \
> +  DECL_FUNC_TERNARY (svint64_t, s, 64) \
> +  DECL_FUNC_TERNARY_FLOAT (svfloat32_t, f, 32) \
> +  DECL_FUNC_TERNARY_FLOAT (svfloat64_t, f, 64)
> +
> +#define TYPES_INDEX(intr) \
> +  DECL_FUNC_INDEX (int8_t, svint8_t, intr, s, 8) \
> +  DECL_FUNC_INDEX (int16_t, svint16_t, intr, s, 16) \
> +  DECL_FUNC_INDEX (int32_t, svint32_t, intr, s, 32) \
> +  DECL_FUNC_INDEX (int64_t, svint64_t, intr, s, 64) \
> +  DECL_FUNC_INDEX_FLOAT (float32_t, svfloat32_t, intr, f, 32) \
> +  DECL_FUNC_INDEX_FLOAT (float64_t, svfloat64_t, intr, f, 64)
> +
> +#define TYPES_INT_BINARY(name, op, intr) \
> +  DECL_FUNC_BINARY (svint8_t, name, op, intr, s, 8) \
> +  DECL_FUNC_BINARY (svint16_t, name, op, intr, s, 16) \
> +  DECL_FUNC_BINARY (svint32_t, name, op, intr, s, 32) \
> +  DECL_FUNC_BINARY (svint64_t, name, op, intr, s, 64)
> +
> +#define TYPES_INT_BINARY_SHIFT(name, op, intr) \
> +  DECL_FUNC_BINARY_SHIFT (svint8_t, name, op, intr, s, 8) \
> +  DECL_FUNC_BINARY_SHIFT (svint16_t, name, op, intr, s, 16) \
> +  DECL_FUNC_BINARY_SHIFT (svint32_t, name, op, intr, s, 32) \
> +  DECL_FUNC_BINARY_SHIFT (svint64_t, name, op, intr, s, 64)
> +
> +#define TYPES_INT_BINARY_CMP(name, op, intr) \
> +  DECL_FUNC_BINARY_CMP (svint8_t, name, op, intr, s, 8) \
> +  DECL_FUNC_BINARY_CMP (svint16_t, name, op, intr, s, 16) \
> +  DECL_FUNC_BINARY_CMP (svint32_t, name, op, intr, s, 32) \
> +  DECL_FUNC_BINARY_CMP (svint64_t, name, op, intr, s, 64) \
> +
> +#define TYPES_INT_BINARY_SCALAR(c, name, op, intr) \
> +  DECL_FUNC_BINARY_SCALAR (c, svint8_t, name, op, intr, s, 8) \
> +  DECL_FUNC_BINARY_SCALAR (c, svint16_t, name, op, intr, s, 16) \
> +  DECL_FUNC_BINARY_SCALAR (c, svint32_t, name, op, intr, s, 32) \
> +  DECL_FUNC_BINARY_SCALAR (c, svint64_t, name, op, intr, s, 64)
> +
> +#define TYPES_FLOAT_BINARY_RET_CMP(name, op, intr) \
> +  DECL_FUNC_BINARY_RET_FLOAT_CMP (svint32_t, svfloat32_t, name, op, intr, f, 32) \
> +  DECL_FUNC_BINARY_RET_FLOAT_CMP (svint64_t, svfloat64_t, name, op, intr, f, 64)
> +
> +#define TYPES_FLOAT_UNARY_RET(name, op, intr) \
> +  DECL_FUNC_UNARY_RET_FLOAT (svint32_t, svfloat32_t, name, op, intr, f, 32) \
> +  DECL_FUNC_UNARY_RET_FLOAT (svint64_t, svfloat64_t, name, op, intr, f, 64)
> +
> +#define TYPES_BINARY_RET_COND(name, op, intr) \
> +  DECL_FUNC_BINARY_RET_COND (svint8_t, svint8_t, name, op, intr, s, 8) \
> +  DECL_FUNC_BINARY_RET_COND (svint16_t, svint16_t, name, op, intr, s, 16) \
> +  DECL_FUNC_BINARY_RET_COND (svint32_t, svint32_t, name, op, intr, s, 32) \
> +  DECL_FUNC_BINARY_RET_COND (svint64_t, svint64_t, name, op, intr, s, 64) \
> +  DECL_FUNC_BINARY_RET_COND (svint32_t, svfloat32_t, name, op, intr, f, 32) \
> +  DECL_FUNC_BINARY_RET_COND (svint64_t, svfloat64_t, name, op, intr, f, 64)
> +
> +#define TYPES_UNARY_RET_COND(name, op, intr) \
> +  DECL_FUNC_UNARY_RET_COND (svint8_t, svint8_t, name, op, intr, s, 8) \
> +  DECL_FUNC_UNARY_RET_COND (svint16_t, svint16_t, name, op, intr, s, 16) \
> +  DECL_FUNC_UNARY_RET_COND (svint32_t, svint32_t, name, op, intr, s, 32) \
> +  DECL_FUNC_UNARY_RET_COND (svint64_t, svint64_t, name, op, intr, s, 64) \
> +  DECL_FUNC_UNARY_RET_COND (svint32_t, svfloat32_t, name, op, intr, f, 32) \
> +  DECL_FUNC_UNARY_RET_COND (svint64_t, svfloat64_t, name, op, intr, f, 64)
> +
> +#define TYPES_INIT() \
> +  DECL_FUNC_INIT (svint8_t, s, 8, 16) \
> +  DECL_FUNC_INIT (svint16_t, s, 16, 8) \
> +  DECL_FUNC_INIT (svint32_t, s, 32, 4) \
> +  DECL_FUNC_INIT (svint64_t, s, 64, 2)
> +
> +#define C_TYPES \
> +    TYPES_INIT () \
> +    TYPES_UNARY (plus, +, svadd_, zr) \
> +    TYPES_UNARY (minus, -, svsub_, zr) \
> +    TYPES_UNARY (plus_plus, ++, svadd_, one) \
> +    TYPES_UNARY (minus_minus, --, svadd_, mone) \
> +    TYPES_INDEX (svget_lane_) \
> +    TYPES_BINARY (plus, +, svadd_) \
> +    TYPES_BINARY (minus, -, svsub_) \
> +    TYPES_BINARY (mult, *, svmul_) \
> +    TYPES_BINARY32_64 (div, /, svdiv_) \
> +    TYPES_INT_BINARY (and, &, svand_) \
> +    TYPES_INT_BINARY (orr, |, svorr_) \
> +    TYPES_INT_UNARY (not, ~, sveor_, mone) \
> +    TYPES_INT_BINARY (eor, ^, sveor_) \
> +    TYPES_INT_BINARY_SHIFT (lshift, <<, svlsl_) \
> +    TYPES_INT_BINARY_SHIFT (rshift, >>, svasr_) \
> +    TYPES_INT_BINARY_SCALAR (2, lshift, <<, svlsl_n_) \
> +    TYPES_INT_BINARY_SCALAR (2, rshift, >>, svasr_n_) \
> +    TYPES_INT_BINARY_CMP (eq, ==, svcmpeq_) \
> +    TYPES_INT_BINARY_CMP (ne, !=, svcmpne_) \
> +    TYPES_INT_BINARY_CMP (gt, >, svcmpgt_) \
> +    TYPES_INT_BINARY_CMP (lt, <, svcmplt_) \
> +    TYPES_INT_BINARY_CMP (ge, >=, svcmpge_) \
> +    TYPES_INT_BINARY_CMP (le, <=, svcmple_) \
> +    TYPES_FLOAT_BINARY_RET_CMP (eq, ==, svcmpeq_) \
> +    TYPES_FLOAT_BINARY_RET_CMP (ne, !=, svcmpne_) \
> +    TYPES_FLOAT_BINARY_RET_CMP (gt, >, svcmpgt_) \
> +    TYPES_FLOAT_BINARY_RET_CMP (lt, <, svcmplt_) \
> +    TYPES_FLOAT_BINARY_RET_CMP (ge, >=, svcmpge_) \
> +    TYPES_FLOAT_BINARY_RET_CMP (le, <=, svcmple_) \
> +
> +#ifdef __cplusplus
> +#define CPP_TYPES \
> +    TYPES_BINARY_RET_COND (and_and, &&, svand_) \
> +    TYPES_BINARY_RET_COND (or_or, ||, svorr_) \
> +    TYPES_UNARY_RET_COND (lnot, !, svnot_z_) \
> +    TYPES_TERNARY ()
> +#endif
> +
> +/* Declare and define functions.  */
> +C_TYPES
> +
> +#ifdef __cplusplus
> +CPP_TYPES
> +#endif
> +
> +#undef DECL_FUNC_UNARY
> +#define DECL_FUNC_UNARY(type, name, op, intr, su, sz, id) \
> +  checkfunc_ ## name ## type ## _unary ();
> +
> +#undef DECL_FUNC_UNARY_FLOAT
> +#define DECL_FUNC_UNARY_FLOAT(type, name, op, intr, su, sz, id) \
> +  checkfunc_ ## name ## type ## _unary ();
> +
> +#undef DECL_FUNC_UNARY_RET_FLOAT
> +#define DECL_FUNC_UNARY_RET_FLOAT(type, name, op, intr, su, sz, id) \
> +  checkfunc_ ## name ## type ## _unary ();
> +
> +#undef DECL_FUNC_INDEX
> +#define DECL_FUNC_INDEX(rtype, type, intr, su, sz) \
> +  checkfunc_ ## rtype ## type ## _vindex (); \
> +  checkfunc_ ## rtype ## type ## _cindex ();
> +
> +#undef DECL_FUNC_INDEX_FLOAT
> +#define DECL_FUNC_INDEX_FLOAT(rtype, type, intr, su, sz) \
> +  checkfunc_ ## rtype ## type ## _vindex (); \
> +  checkfunc_ ## rtype ## type ## _cindex ();
> +
> +#undef DECL_FUNC_BINARY
> +#define DECL_FUNC_BINARY(type, name, op, intr, su, sz) \
> +  checkfunc_ ## name ## type ## _binary ();
> +
> +#undef DECL_FUNC_BINARY_SHIFT
> +#define DECL_FUNC_BINARY_SHIFT(type, name, op, intr, su, sz) \
> +  checkfunc_ ## name ## type ## _binary ();
> +
> +#undef DECL_FUNC_BINARY_FLOAT
> +#define DECL_FUNC_BINARY_FLOAT(type, name, op, intr, su, sz) \
> +  checkfunc_ ## name ## type ## _binary ();
> +
> +#undef DECL_FUNC_BINARY_CMP
> +#define DECL_FUNC_BINARY_CMP(type, name, op, intr, su, sz)  \
> +  checkfunc_ ## name ## type ## _binary_cmp ();
> +
> +#undef DECL_FUNC_TERNARY
> +#define DECL_FUNC_TERNARY(type, su, sz) \
> +  checkfunc_ ## type ## _ternary ();
> +
> +#undef DECL_FUNC_INIT
> +#define DECL_FUNC_INIT(type, su, sz, nelem) \
> +  checkfunc_ ## type ## _init ();
> +
> +#undef DECL_FUNC_TERNARY_FLOAT
> +#define DECL_FUNC_TERNARY_FLOAT(type, su, sz) \
> +  checkfunc_ ## type ## _ternary ();
> +
> +#undef DECL_FUNC_BINARY_SCALAR
> +#define DECL_FUNC_BINARY_SCALAR(scalar, type, name, op, intr, su, sz) \
> +  checkfunc_ ## name  ## type ## _binary_cscalar (); \
> +  checkfunc_ ## name  ## type ## _binary_vscalar ();
> +
> +#undef DECL_FUNC_BINARY_RET_FLOAT_CMP
> +#define DECL_FUNC_BINARY_RET_FLOAT_CMP(rtype, type, name, op, intr, su, sz) \
> +  checkfunc_ ## name  ## rtype ## type ## _binary_cmp ();
> +
> +#undef DECL_FUNC_BINARY_RET_COND
> +#define DECL_FUNC_BINARY_RET_COND(rtype, type, name, op, intr, su, sz)  \
> +  checkfunc_ ## name ## rtype ## type ## _binary_cond ();
> +
> +#undef DECL_FUNC_UNARY_RET_COND
> +#define DECL_FUNC_UNARY_RET_COND(rtype, type, name, op, intr, su, sz)  \
> +  checkfunc_ ## name ## rtype ## type ## _unary_cond ();
> +
> +int
> +main (void)
> +{
> +  C_TYPES
> +
> +#ifdef __cplusplus
> +  CPP_TYPES
> +#endif
> +
> +  return 0;
> +}
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops.c
new file mode 100644
index 00000000000..28da602301e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops.c
@@ -0,0 +1,570 @@ 
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+#include <stdio.h>
+
+#define DECL_FUNC_UNARY(type, name, op, intr, su, sz, id) \
+  __attribute__ ((noipa)) \
+  type func_ ## name ## type ## _unary (type a) { \
+    return op (a); \
+  } \
+  void checkfunc_ ## name ## type ## _unary () { \
+    type data = svindex_ ## su ## sz (0, 1); \
+    type zr = svindex_ ## su ## sz (0, 0); \
+    type one = svindex_ ## su ## sz (1, 0); \
+    type mone = svindex_ ## su ## sz (-1, 0); \
+    svbool_t pg = svptrue_b ## sz (); \
+    type exp = intr ## su ## sz ## _z (pg, id, data); \
+    type actual = func_ ## name ## type ## _unary (data); \
+    svbool_t res = svcmpeq_ ## su ## sz (pg, exp, actual); \
+    if (svptest_any (pg, svnot_b_z (pg, res))) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_UNARY_FLOAT(type, name, op, intr, su, sz, id) \
+  __attribute__ ((noipa)) \
+  type func_ ## name ## type ## _unary (type a) { \
+    return op (a); \
+  } \
+  void checkfunc_ ## name ## type ## _unary () { \
+    type data = svdup_n_ ## su ## sz (2.0); \
+    type zr = svdup_n_ ## su ## sz (0.0); \
+    type one = svdup_n_ ## su ## sz (1.0); \
+    type mone = svdup_n_ ## su ## sz (-1.0); \
+    svbool_t pg = svptrue_b ## sz (); \
+    type exp = intr ## su ## sz ## _z (pg, id, data); \
+    type actual = func_ ## name ## type ## _unary (data); \
+    svbool_t res = svcmpeq_ ## su ## sz (pg, exp, actual); \
+    if (svptest_any (pg, svnot_b_z (pg, res))) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_INDEX(rtype, type, intr, su, sz)  \
+  __attribute__ ((noipa)) \
+  rtype func_ ## rtype ## type ## _vindex (type a, int n) { \
+    return (a[n]); \
+  } \
+  __attribute__ ((noipa)) \
+  rtype func_ ## rtype ## type ## _cindex (type a) { \
+    return (a[0]); \
+  } \
+  void checkfunc_ ## rtype ## type ## _vindex () { \
+    type a = svindex_ ## su ## sz (0, 1); \
+    int n = 2; \
+    if (2 != func_ ## rtype ## type ## _vindex (a, n)) \
+      __builtin_abort (); \
+  } \
+  void checkfunc_ ## rtype ## type ## _cindex () { \
+    type a = svindex_ ## su ## sz (1, 0); \
+    if (1 != func_ ## rtype ## type ## _cindex (a)) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_INDEX_FLOAT(rtype, type, intr, su, sz)  \
+  __attribute__ ((noipa)) \
+  rtype func_ ## rtype ## type ## _vindex (type a, int n) { \
+    return (a[n]); \
+  } \
+  __attribute__ ((noipa)) \
+  rtype func_ ## rtype ## type ## _cindex (type a) { \
+    return (a[0]); \
+  } \
+  void checkfunc_ ## rtype ## type ## _vindex () { \
+    type a = svdup_n_ ## su ## sz (2.0); \
+    int n = 2; \
+    if (2.0 != func_ ## rtype ## type ## _vindex (a, n)) \
+      __builtin_abort (); \
+  } \
+  void checkfunc_ ## rtype ## type ## _cindex () { \
+    type a = svdup_n_ ## su ## sz (4.0); \
+    if (4.0 != func_ ## rtype ## type ## _cindex (a)) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_BINARY(type, name, op, intr, su, sz)  \
+  __attribute__ ((noipa)) \
+  type func_ ## name  ## type ## _binary(type a, type b) { \
+    return (a) op (b); \
+  } \
+  void checkfunc_ ## name ## type ## _binary () { \
+    type a = svindex_ ## su ## sz (0, 1); \
+    type b = svindex_ ## su ## sz (0, 2); \
+    svbool_t all_true = svptrue_b ## sz (); \
+    type exp = intr ## su ## sz ## _z (all_true, a, b); \
+    type actual = func_ ## name ## type ## _binary (a, b); \
+    svbool_t res = svcmpeq_ ## su ## sz (all_true, exp, actual); \
+    if (svptest_any (all_true, svnot_b_z (all_true, res))) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_BINARY_SHIFT(type, name, op, intr, su, sz)  \
+  __attribute__ ((noipa)) \
+  type func_ ## name  ## type ## _binary(type a, type b) { \
+    return (a) op (b); \
+  } \
+  void checkfunc_ ## name ## type ## _binary () { \
+    type a = svindex_ ## su ## sz (0, 1); \
+    svuint ## sz ## _t b = svindex_u ## sz (0, 2); \
+    type c = svindex_ ## su ## sz (0, 2); \
+    svbool_t all_true = svptrue_b ## sz (); \
+    type exp = intr ## su ## sz ## _z (all_true, a, b); \
+    type actual = func_ ## name ## type ## _binary (a, c); \
+    svbool_t res = svcmpeq_ ## su ## sz (all_true, exp, actual); \
+    if (svptest_any (all_true, svnot_b_z (all_true, res))) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_BINARY_FLOAT(type, name, op, intr, su, sz)  \
+  __attribute__ ((noipa)) \
+  type func_ ## name  ## type ## _binary(type a, type b) { \
+    return (a) op (b); \
+  } \
+  void checkfunc_ ## name ## type ## _binary () { \
+    type a = svdup_n_ ## su ## sz (1.0); \
+    type b = svdup_n_ ## su ## sz (2.0); \
+    svbool_t all_true = svptrue_b ## sz (); \
+    type exp = intr ## su ## sz ## _z (all_true, a, b); \
+    type actual = func_ ## name ## type ## _binary (a, b); \
+    svbool_t res = svcmpeq_ ## su ## sz (all_true, exp, actual); \
+    if (svptest_any (all_true, svnot_b_z (all_true, res))) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_BINARY_CMP(type, name, op, intr, su, sz)  \
+  __attribute__ ((noipa)) \
+  type func_ ## name  ## type ## _binary_cmp(type a, type b) { \
+    return (a) op (b); \
+  } \
+  void checkfunc_ ## name ## type ## _binary_cmp () { \
+    type a = svindex_ ## su ## sz (0, 1); \
+    type b = svindex_ ## su ## sz (0, 2); \
+    type c = func_ ## name ## type ## _binary_cmp (a, b); \
+    svbool_t all_true = svptrue_b ## sz (); \
+    svbool_t pgc = svcmpne_n_ ## su ## sz (all_true, c, 0); \
+    svbool_t pg = intr ## su ## sz (all_true, a, b); \
+    svbool_t res = sveor_b_z (all_true, pgc, pg); \
+    if (svptest_any (all_true, res)) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_TERNARY(type, su, sz) \
+  __attribute__ ((noipa)) \
+  type func_ ## type ## _ternary(type p, type q, type a, type b) { \
+    return (p >= q) ? a : b; \
+  } \
+  void checkfunc_ ## type ## _ternary() { \
+    type p = svindex_ ## su ## sz (0, 1); \
+    type q = svindex_ ## su ## sz (1, 1); \
+    type a = svindex_ ## su ## sz (2, 1); \
+    type b = svindex_ ## su ## sz (3, 1); \
+    svbool_t all_true = svptrue_b ## sz (); \
+    svbool_t cmp = svcmpge_ ## su ## sz (all_true, p, q); \
+    type res = svsel_ ## su ## sz (cmp, a, b); \
+    type actual = func_ ## type ## _ternary(p, q, a, b); \
+    svbool_t pgc = svcmpeq_ ## su ## sz (all_true, res, actual); \
+    if (svptest_any (all_true, svnot_b_z (all_true, pgc))) \
+      __builtin_abort (); \
+  }
+
+#define VECT_CST_s8  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
+#define VECT_CST_s16 { 0, 1, 2, 3, 4, 5, 6, 7 }
+#define VECT_CST_s32 { 0, 1, 2, 3 }
+#define VECT_CST_s64 { 0, 1 }
+
+#define DECL_FUNC_INIT(type, su, sz, nelem) \
+  __attribute__ ((noipa)) \
+  type func_ ## type ## _init1() { \
+    type temp = VECT_CST_ ## su ## sz; \
+    return temp; \
+  } \
+  __attribute__ ((noipa)) \
+  type func_ ## type ## _init2() { \
+    type temp = { 0 }; \
+    return temp; \
+  } \
+  __attribute__ ((noipa)) \
+  type func_ ## type ## _init3() { \
+    type temp = { }; \
+    return temp; \
+  } \
+  __attribute__ ((noipa)) \
+  type func_ ## type ## _init4() { \
+    type temp = VECT_CST_ ## su ## sz; \
+    return temp; \
+  } \
+  void checkfunc_ ## type ## _init() { \
+    svbool_t all_true = svptrue_b ## sz (); \
+    int ## sz ## _t mem[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; \
+    svbool_t cmp ## sz = svptrue_pat_b ## sz (SV_VL ## nelem); \
+    type init1 = svld1_ ## su ## sz (cmp ## sz, mem); \
+    type init2 = svindex_ ## su ## sz (0, 0); \
+    type init3 = svindex_ ## su ## sz (0, 0); \
+    type init4 = svld1_ ## su ## sz (cmp ## sz, mem); \
+	\
+    type res_init1 = func_ ## type ## _init1 (); \
+    svbool_t cmp = svcmpne_ ## su ## sz (all_true, init1, res_init1); \
+    if (svptest_any (all_true, cmp)) \
+      __builtin_abort (); \
+	\
+    type res_init2 = func_ ## type ## _init2 (); \
+    cmp = svcmpne_ ## su ## sz (all_true, init2, res_init2); \
+    if (svptest_any (all_true, cmp)) \
+      __builtin_abort (); \
+	\
+    type res_init3 = func_ ## type ## _init3 (); \
+    cmp = svcmpne_ ## su ## sz (all_true, init3, res_init3); \
+    if (svptest_any (all_true, cmp)) \
+      __builtin_abort (); \
+	\
+    type res_init4 = func_ ## type ## _init4 (); \
+    cmp = svcmpne_ ## su ## sz (all_true, init4, res_init4); \
+    if (svptest_any (all_true, cmp)) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_TERNARY_FLOAT(type, su, sz) \
+  __attribute__ ((noipa)) \
+  type func_ ## type ## _ternary(type p, type q, type a, type b) { \
+    return (p >= q) ? a : b; \
+  } \
+  void checkfunc_ ## type ## _ternary() { \
+    type p = svdup_n_ ## su ## sz (2.0); \
+    type q = svdup_n_ ## su ## sz (1.0); \
+    type a = svdup_n_ ## su ## sz (3.0); \
+    type b = svdup_n_ ## su ## sz (4.0); \
+    svbool_t all_true = svptrue_b ## sz (); \
+    svbool_t cmp = svcmpge_ ## su ## sz (all_true, p, q); \
+    type res = svsel_ ## su ## sz (cmp, a, b); \
+    type actual = func_ ## type ## _ternary(p, q, a, b); \
+    svbool_t pgc = svcmpeq_ ## su ## sz (all_true, res, actual); \
+    if (svptest_any (all_true, svnot_b_z (all_true, pgc))) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_BINARY_SCALAR(scalar, type, name, op, intr, su, sz)  \
+  __attribute__ ((noipa)) \
+  type func_ ## name  ## type ## _binary_cscalar(type a) { \
+    return (a) op scalar; \
+  } \
+  __attribute__ ((noipa)) \
+  type func_ ## name  ## type ## _binary_vscalar(type a, int b) { \
+    return (a) op b; \
+  } \
+  void checkfunc_ ## name ## type ## _binary_cscalar () { \
+    type a = svindex_ ## su ## sz (0, 1); \
+    svbool_t pg = svptrue_b ## sz (); \
+    type exp = intr ## su ## sz ## _z (pg, a, scalar); \
+    type actual = func_ ## name ## type ## _binary_cscalar (a); \
+    svbool_t res = svcmpeq_ ## su ## sz (pg, exp, actual); \
+    if (svptest_any (pg, svnot_b_z (pg, res))) \
+      __builtin_abort (); \
+  } \
+  void checkfunc_ ## name ## type ## _binary_vscalar () { \
+    type a = svindex_ ## su ## sz (0, 1); \
+    svbool_t pg = svptrue_b ## sz (); \
+    uint ## sz ## _t b = scalar; \
+    type exp = intr ## su ## sz ## _z (pg, a, b); \
+    type actual = func_ ## name ## type ## _binary_vscalar (a, b); \
+    svbool_t res = svcmpeq_ ## su ## sz (pg, exp, actual); \
+    if (svptest_any (pg, svnot_b_z (pg, res))) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_UNARY_RET_FLOAT(rtype, type, name, op, intr, su, sz)  \
+  __attribute__ ((noipa)) \
+  rtype func_ ## name  ## rtype ## type ## _unary(type a) { \
+    return op (a); \
+  } \
+  void checkfunc_ ## name ## rtype ## type ## _unary () { \
+    type a = svdup_n_ ## su ## sz (2.0); \
+    svbool_t pg = svptrue_b ## sz (); \
+    rtype exp = intr ## su ## sz ## _z (a); \
+    rtype actual = func_ ## name ## type ## _unary (a); \
+    svbool_t res = svcmpeq_ ## su ## sz (pg, exp, actual); \
+    if (svptest_any (pg, svnot_b_z (pg, res))) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_BINARY_RET_FLOAT_CMP(rtype, type, name, op, intr, su, sz)  \
+  __attribute__ ((noipa)) \
+  rtype func_ ## name  ## rtype ## type ## _binary_cmp(type a, type b) { \
+    return (a) op (b); \
+  } \
+  void checkfunc_ ## name ## rtype ## type ## _binary_cmp () { \
+    type a = svdup_n_ ## su ## sz (2.0); \
+    type b = svdup_n_ ## su ## sz (3.0); \
+    svbool_t all_true = svptrue_b ## sz (); \
+    rtype cmp = func_ ## name ## rtype ## type ## _binary_cmp (a, b); \
+    svbool_t pgc = intr ## su ## sz (all_true, a, b) ; \
+    svbool_t pg = svcmpne_n_s ## sz (all_true, cmp, 0); \
+    svbool_t res = sveor_b_z (all_true, pg, pgc); \
+    if (svptest_any (all_true, res)) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_BINARY_RET_COND(rtype, type, name, op, intr, su, sz)  \
+  __attribute__ ((noipa)) \
+  rtype func_ ## name  ## rtype ## type ## _binary_cond(type a, type b) { \
+    return (a) op (b); \
+  } \
+  __attribute__ ((noipa)) \
+  svbool_t name ## intr ## su ## sz (svbool_t t, type a, type b) { \
+    svbool_t pgl = svcmpne_n_ ## su ## sz (t, a, 0); \
+    svbool_t pgr = svcmpne_n_ ## su ## sz (t, b, 0); \
+    return intr ## b_z (t, pgl, pgr); \
+  } \
+  void checkfunc_ ## name ## rtype ## type ## _binary_cond () { \
+    type a = svdup_n_ ## su ## sz (2); \
+    type b = svdup_n_ ## su ## sz (3); \
+    svbool_t all_true = svptrue_b ## sz (); \
+    rtype cmp = func_ ## name ## rtype ## type ## _binary_cond (a, b); \
+    svbool_t pgc = name ## intr ## su ## sz (all_true, a, b) ; \
+    svbool_t pg = svcmpne_n_s ## sz (all_true, cmp, 0); \
+    svbool_t res = sveor_b_z (all_true, pg, pgc); \
+    if (svptest_any (all_true, res)) \
+      __builtin_abort (); \
+  }
+
+#define DECL_FUNC_UNARY_RET_COND(rtype, type, name, op, intr, su, sz)  \
+  __attribute__ ((noipa)) \
+  rtype func_ ## name  ## rtype ## type ## _unary_cond (type a) { \
+    return op (a); \
+  } \
+  __attribute__ ((noipa)) \
+  svbool_t name ## intr ## su ## sz (svbool_t t, type a) { \
+    svbool_t pgl = svcmpeq_n_ ## su ## sz (t, a, 0); \
+    return pgl; \
+  } \
+  void checkfunc_ ## name ## rtype ## type ## _unary_cond () { \
+    type a = svdup_n_ ## su ## sz (2); \
+    svbool_t all_true = svptrue_b ## sz (); \
+    rtype cmp = func_ ## name ## rtype ## type ## _unary_cond (a); \
+    svbool_t pgc = name ## intr ## su ## sz (all_true, a) ; \
+    svbool_t pg = svcmpne_n_s ## sz (all_true, cmp, 0); \
+    svbool_t res = sveor_b_z (all_true, pg, pgc); \
+    if (svptest_any (all_true, res)) \
+      __builtin_abort (); \
+  }
+
+#define TYPES_UNARY(name, op, intr, id) \
+  DECL_FUNC_UNARY (svint8_t, name, op, intr, s, 8, id) \
+  DECL_FUNC_UNARY (svint16_t, name, op, intr, s, 16, id) \
+  DECL_FUNC_UNARY (svint32_t, name, op, intr, s, 32, id) \
+  DECL_FUNC_UNARY (svint64_t, name, op, intr, s, 64, id) \
+  DECL_FUNC_UNARY_FLOAT (svfloat32_t, name, op, intr, f, 32, id) \
+  DECL_FUNC_UNARY_FLOAT (svfloat64_t, name, op, intr, f, 64, id)
+
+#define TYPES_INT_UNARY(name, op, intr, id) \
+  DECL_FUNC_UNARY (svint8_t, name, op, intr, s, 8, id) \
+  DECL_FUNC_UNARY (svint16_t, name, op, intr, s, 16, id) \
+  DECL_FUNC_UNARY (svint32_t, name, op, intr, s, 32, id) \
+  DECL_FUNC_UNARY (svint64_t, name, op, intr, s, 64, id)
+
+#define TYPES_BINARY(name, op, intr) \
+  DECL_FUNC_BINARY (svint8_t, name, op, intr, s, 8) \
+  DECL_FUNC_BINARY (svint16_t, name, op, intr, s, 16) \
+  DECL_FUNC_BINARY (svint32_t, name, op, intr, s, 32) \
+  DECL_FUNC_BINARY (svint64_t, name, op, intr, s, 64) \
+  DECL_FUNC_BINARY_FLOAT (svfloat32_t, name, op, intr, f, 32) \
+  DECL_FUNC_BINARY_FLOAT (svfloat64_t, name, op, intr, f, 64)
+
+#define TYPES_BINARY32_64(name, op, intr) \
+  DECL_FUNC_BINARY (svint32_t, name, op, intr, s, 32) \
+  DECL_FUNC_BINARY (svint64_t, name, op, intr, s, 64)
+
+#define TYPES_TERNARY() \
+  DECL_FUNC_TERNARY (svint8_t, s, 8) \
+  DECL_FUNC_TERNARY (svint16_t, s, 16) \
+  DECL_FUNC_TERNARY (svint32_t, s, 32) \
+  DECL_FUNC_TERNARY (svint64_t, s, 64) \
+  DECL_FUNC_TERNARY_FLOAT (svfloat32_t, f, 32) \
+  DECL_FUNC_TERNARY_FLOAT (svfloat64_t, f, 64)
+
+#define TYPES_INDEX(intr) \
+  DECL_FUNC_INDEX (int8_t, svint8_t, intr, s, 8) \
+  DECL_FUNC_INDEX (int16_t, svint16_t, intr, s, 16) \
+  DECL_FUNC_INDEX (int32_t, svint32_t, intr, s, 32) \
+  DECL_FUNC_INDEX (int64_t, svint64_t, intr, s, 64) \
+  DECL_FUNC_INDEX_FLOAT (float32_t, svfloat32_t, intr, f, 32) \
+  DECL_FUNC_INDEX_FLOAT (float64_t, svfloat64_t, intr, f, 64)
+
+#define TYPES_INT_BINARY(name, op, intr) \
+  DECL_FUNC_BINARY (svint8_t, name, op, intr, s, 8) \
+  DECL_FUNC_BINARY (svint16_t, name, op, intr, s, 16) \
+  DECL_FUNC_BINARY (svint32_t, name, op, intr, s, 32) \
+  DECL_FUNC_BINARY (svint64_t, name, op, intr, s, 64)
+
+#define TYPES_INT_BINARY_SHIFT(name, op, intr) \
+  DECL_FUNC_BINARY_SHIFT (svint8_t, name, op, intr, s, 8) \
+  DECL_FUNC_BINARY_SHIFT (svint16_t, name, op, intr, s, 16) \
+  DECL_FUNC_BINARY_SHIFT (svint32_t, name, op, intr, s, 32) \
+  DECL_FUNC_BINARY_SHIFT (svint64_t, name, op, intr, s, 64)
+
+#define TYPES_INT_BINARY_CMP(name, op, intr) \
+  DECL_FUNC_BINARY_CMP (svint8_t, name, op, intr, s, 8) \
+  DECL_FUNC_BINARY_CMP (svint16_t, name, op, intr, s, 16) \
+  DECL_FUNC_BINARY_CMP (svint32_t, name, op, intr, s, 32) \
+  DECL_FUNC_BINARY_CMP (svint64_t, name, op, intr, s, 64) \
+
+#define TYPES_INT_BINARY_SCALAR(c, name, op, intr) \
+  DECL_FUNC_BINARY_SCALAR (c, svint8_t, name, op, intr, s, 8) \
+  DECL_FUNC_BINARY_SCALAR (c, svint16_t, name, op, intr, s, 16) \
+  DECL_FUNC_BINARY_SCALAR (c, svint32_t, name, op, intr, s, 32) \
+  DECL_FUNC_BINARY_SCALAR (c, svint64_t, name, op, intr, s, 64)
+
+#define TYPES_FLOAT_BINARY_RET_CMP(name, op, intr) \
+  DECL_FUNC_BINARY_RET_FLOAT_CMP (svint32_t, svfloat32_t, name, op, intr, f, 32) \
+  DECL_FUNC_BINARY_RET_FLOAT_CMP (svint64_t, svfloat64_t, name, op, intr, f, 64)
+
+#define TYPES_FLOAT_UNARY_RET(name, op, intr) \
+  DECL_FUNC_UNARY_RET_FLOAT (svint32_t, svfloat32_t, name, op, intr, f, 32) \
+  DECL_FUNC_UNARY_RET_FLOAT (svint64_t, svfloat64_t, name, op, intr, f, 64)
+
+#define TYPES_BINARY_RET_COND(name, op, intr) \
+  DECL_FUNC_BINARY_RET_COND (svint8_t, svint8_t, name, op, intr, s, 8) \
+  DECL_FUNC_BINARY_RET_COND (svint16_t, svint16_t, name, op, intr, s, 16) \
+  DECL_FUNC_BINARY_RET_COND (svint32_t, svint32_t, name, op, intr, s, 32) \
+  DECL_FUNC_BINARY_RET_COND (svint64_t, svint64_t, name, op, intr, s, 64) \
+  DECL_FUNC_BINARY_RET_COND (svint32_t, svfloat32_t, name, op, intr, f, 32) \
+  DECL_FUNC_BINARY_RET_COND (svint64_t, svfloat64_t, name, op, intr, f, 64)
+
+#define TYPES_UNARY_RET_COND(name, op, intr) \
+  DECL_FUNC_UNARY_RET_COND (svint8_t, svint8_t, name, op, intr, s, 8) \
+  DECL_FUNC_UNARY_RET_COND (svint16_t, svint16_t, name, op, intr, s, 16) \
+  DECL_FUNC_UNARY_RET_COND (svint32_t, svint32_t, name, op, intr, s, 32) \
+  DECL_FUNC_UNARY_RET_COND (svint64_t, svint64_t, name, op, intr, s, 64) \
+  DECL_FUNC_UNARY_RET_COND (svint32_t, svfloat32_t, name, op, intr, f, 32) \
+  DECL_FUNC_UNARY_RET_COND (svint64_t, svfloat64_t, name, op, intr, f, 64)
+
+#define TYPES_INIT() \
+  DECL_FUNC_INIT (svint8_t, s, 8, 16) \
+  DECL_FUNC_INIT (svint16_t, s, 16, 8) \
+  DECL_FUNC_INIT (svint32_t, s, 32, 4) \
+  DECL_FUNC_INIT (svint64_t, s, 64, 2)
+
+#define C_TYPES \
+    TYPES_INIT () \
+    TYPES_UNARY (plus, +, svadd_, zr) \
+    TYPES_UNARY (minus, -, svsub_, zr) \
+    TYPES_UNARY (plus_plus, ++, svadd_, one) \
+    TYPES_UNARY (minus_minus, --, svadd_, mone) \
+    TYPES_INDEX (svget_lane_) \
+    TYPES_BINARY (plus, +, svadd_) \
+    TYPES_BINARY (minus, -, svsub_) \
+    TYPES_BINARY (mult, *, svmul_) \
+    TYPES_BINARY32_64 (div, /, svdiv_) \
+    TYPES_INT_BINARY (and, &, svand_) \
+    TYPES_INT_BINARY (orr, |, svorr_) \
+    TYPES_INT_UNARY (not, ~, sveor_, mone) \
+    TYPES_INT_BINARY (eor, ^, sveor_) \
+    TYPES_INT_BINARY_SHIFT (lshift, <<, svlsl_) \
+    TYPES_INT_BINARY_SHIFT (rshift, >>, svasr_) \
+    TYPES_INT_BINARY_SCALAR (2, lshift, <<, svlsl_n_) \
+    TYPES_INT_BINARY_SCALAR (2, rshift, >>, svasr_n_) \
+    TYPES_INT_BINARY_CMP (eq, ==, svcmpeq_) \
+    TYPES_INT_BINARY_CMP (ne, !=, svcmpne_) \
+    TYPES_INT_BINARY_CMP (gt, >, svcmpgt_) \
+    TYPES_INT_BINARY_CMP (lt, <, svcmplt_) \
+    TYPES_INT_BINARY_CMP (ge, >=, svcmpge_) \
+    TYPES_INT_BINARY_CMP (le, <=, svcmple_) \
+    TYPES_FLOAT_BINARY_RET_CMP (eq, ==, svcmpeq_) \
+    TYPES_FLOAT_BINARY_RET_CMP (ne, !=, svcmpne_) \
+    TYPES_FLOAT_BINARY_RET_CMP (gt, >, svcmpgt_) \
+    TYPES_FLOAT_BINARY_RET_CMP (lt, <, svcmplt_) \
+    TYPES_FLOAT_BINARY_RET_CMP (ge, >=, svcmpge_) \
+    TYPES_FLOAT_BINARY_RET_CMP (le, <=, svcmple_) \
+
+#ifdef __cplusplus
+#define CPP_TYPES \
+    TYPES_BINARY_RET_COND (and_and, &&, svand_) \
+    TYPES_BINARY_RET_COND (or_or, ||, svorr_) \
+    TYPES_UNARY_RET_COND (lnot, !, svnot_z_) \
+    TYPES_TERNARY ()
+#endif
+
+/* Declare and define functions.  */
+C_TYPES
+
+#ifdef __cplusplus
+CPP_TYPES
+#endif
+
+#undef DECL_FUNC_UNARY
+#define DECL_FUNC_UNARY(type, name, op, intr, su, sz, id) \
+  checkfunc_ ## name ## type ## _unary ();
+
+#undef DECL_FUNC_UNARY_FLOAT
+#define DECL_FUNC_UNARY_FLOAT(type, name, op, intr, su, sz, id) \
+  checkfunc_ ## name ## type ## _unary ();
+
+#undef DECL_FUNC_UNARY_RET_FLOAT
+#define DECL_FUNC_UNARY_RET_FLOAT(type, name, op, intr, su, sz, id) \
+  checkfunc_ ## name ## type ## _unary ();
+
+#undef DECL_FUNC_INDEX
+#define DECL_FUNC_INDEX(rtype, type, intr, su, sz) \
+  checkfunc_ ## rtype ## type ## _vindex (); \
+  checkfunc_ ## rtype ## type ## _cindex ();
+
+#undef DECL_FUNC_INDEX_FLOAT
+#define DECL_FUNC_INDEX_FLOAT(rtype, type, intr, su, sz) \
+  checkfunc_ ## rtype ## type ## _vindex (); \
+  checkfunc_ ## rtype ## type ## _cindex ();
+
+#undef DECL_FUNC_BINARY
+#define DECL_FUNC_BINARY(type, name, op, intr, su, sz) \
+  checkfunc_ ## name ## type ## _binary ();
+
+#undef DECL_FUNC_BINARY_SHIFT
+#define DECL_FUNC_BINARY_SHIFT(type, name, op, intr, su, sz) \
+  checkfunc_ ## name ## type ## _binary ();
+
+#undef DECL_FUNC_BINARY_FLOAT
+#define DECL_FUNC_BINARY_FLOAT(type, name, op, intr, su, sz) \
+  checkfunc_ ## name ## type ## _binary ();
+
+#undef DECL_FUNC_BINARY_CMP
+#define DECL_FUNC_BINARY_CMP(type, name, op, intr, su, sz)  \
+  checkfunc_ ## name ## type ## _binary_cmp ();
+
+#undef DECL_FUNC_TERNARY
+#define DECL_FUNC_TERNARY(type, su, sz) \
+  checkfunc_ ## type ## _ternary ();
+
+#undef DECL_FUNC_INIT
+#define DECL_FUNC_INIT(type, su, sz, nelem) \
+  checkfunc_ ## type ## _init ();
+
+#undef DECL_FUNC_TERNARY_FLOAT
+#define DECL_FUNC_TERNARY_FLOAT(type, su, sz) \
+  checkfunc_ ## type ## _ternary ();
+
+#undef DECL_FUNC_BINARY_SCALAR
+#define DECL_FUNC_BINARY_SCALAR(scalar, type, name, op, intr, su, sz) \
+  checkfunc_ ## name  ## type ## _binary_cscalar (); \
+  checkfunc_ ## name  ## type ## _binary_vscalar ();
+
+#undef DECL_FUNC_BINARY_RET_FLOAT_CMP
+#define DECL_FUNC_BINARY_RET_FLOAT_CMP(rtype, type, name, op, intr, su, sz) \
+  checkfunc_ ## name  ## rtype ## type ## _binary_cmp ();
+
+#undef DECL_FUNC_BINARY_RET_COND
+#define DECL_FUNC_BINARY_RET_COND(rtype, type, name, op, intr, su, sz)  \
+  checkfunc_ ## name ## rtype ## type ## _binary_cond ();
+
+#undef DECL_FUNC_UNARY_RET_COND
+#define DECL_FUNC_UNARY_RET_COND(rtype, type, name, op, intr, su, sz)  \
+  checkfunc_ ## name ## rtype ## type ## _unary_cond ();
+
+int
+main (void)
+{
+  C_TYPES
+
+#ifdef __cplusplus
+  CPP_TYPES
+#endif
+
+  return 0;
+}