Hi, changes from v1: - Removed UNSPEC_VNCOPYSIGN - Adjusted xorsign test expectation.
Regards Robin This adds vector copysign, ncopysign and xorsign as well as the accompanying tests. gcc/ChangeLog: * config/riscv/autovec.md (copysign<mode>3): Add expander. (xorsign<mode>3): Dito. * config/riscv/riscv-vector-builtins-bases.cc (class vfsgnjn): New class. * config/riscv/vector-iterators.md (copysign): Remove ncopysign. (xorsign): Dito. (n): Dito. (x): Dito. * config/riscv/vector.md (@pred_ncopysign<mode>): Split off. (@pred_ncopysign<mode>_scalar): Dito. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/binop/copysign-run.c: New test. * gcc.target/riscv/rvv/autovec/binop/copysign-rv64gcv.c: New test. * gcc.target/riscv/rvv/autovec/binop/copysign-rv32gcv.c: New test. * gcc.target/riscv/rvv/autovec/binop/copysign-template.h: New test. * gcc.target/riscv/rvv/autovec/binop/copysign-zvfh-run.c: New test. --- gcc/config/riscv/autovec.md | 43 +++++++++ .../riscv/riscv-vector-builtins-bases.cc | 18 +++- gcc/config/riscv/vector-iterators.md | 10 +-- gcc/config/riscv/vector.md | 43 +++++++++ .../riscv/rvv/autovec/binop/copysign-run.c | 89 +++++++++++++++++++ .../rvv/autovec/binop/copysign-rv32gcv.c | 11 +++ .../rvv/autovec/binop/copysign-rv64gcv.c | 11 +++ .../rvv/autovec/binop/copysign-template.h | 78 ++++++++++++++++ .../rvv/autovec/binop/copysign-zvfh-run.c | 83 +++++++++++++++++ 9 files changed, 377 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-run.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv32gcv.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv64gcv.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-template.h create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-zvfh-run.c diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index f1641d7e1ea..f2e69aaf102 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -804,3 +804,46 @@ (define_expand "<optab><mode>3" riscv_vector::RVV_BINOP, operands); DONE; }) + +;; ------------------------------------------------------------------------------- +;; ---- [FP] Sign copying +;; ------------------------------------------------------------------------------- +;; Includes: +;; - vfsgnj.vv/vfsgnjn.vv +;; - vfsgnj.vf/vfsgnjn.vf +;; ------------------------------------------------------------------------------- + +;; Leave the pattern like this as to still allow combine to match +;; a negated copysign (see vector.md) before adding the UNSPEC_VPREDICATE later. +(define_insn_and_split "copysign<mode>3" + [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr") + (unspec:VF + [(match_operand:VF 1 "register_operand" " vr, vr, vr, vr") + (match_operand:VF 2 "register_operand" " vr, vr, vr, vr")] UNSPEC_VCOPYSIGN))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] +{ + riscv_vector::emit_vlmax_insn (code_for_pred (UNSPEC_VCOPYSIGN, <MODE>mode), + riscv_vector::RVV_BINOP, operands); + DONE; +} + [(set_attr "type" "vfsgnj") + (set_attr "mode" "<MODE>")]) + +;; ------------------------------------------------------------------------------- +;; Includes: +;; - vfsgnjx.vv +;; - vfsgnjx.vf +;; ------------------------------------------------------------------------------- +(define_expand "xorsign<mode>3" + [(match_operand:VF_AUTO 0 "register_operand") + (match_operand:VF_AUTO 1 "register_operand") + (match_operand:VF_AUTO 2 "register_operand")] + "TARGET_VECTOR" +{ + riscv_vector::emit_vlmax_insn (code_for_pred (UNSPEC_VXORSIGN, <MODE>mode), + riscv_vector::RVV_BINOP, operands); + DONE; +}) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index c6c53dc13a5..6b8fec47ac9 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -1212,7 +1212,7 @@ public: } }; -/* Implements vfsqrt7/vfrec7/vfclass/vfsgnj/vfsgnjn/vfsgnjx. */ +/* Implements vfsqrt7/vfrec7/vfclass/vfsgnj/vfsgnjx. */ template<int UNSPEC> class float_misc : public function_base { @@ -1227,6 +1227,20 @@ public: } }; +/* Implements vfsgnjn. */ +class vfsgnjn : public function_base +{ +public: + rtx expand (function_expander &e) const override + { + if (e.op_info->op == OP_TYPE_vf) + return e.use_exact_insn (code_for_pred_ncopysign_scalar (e.vector_mode ())); + if (e.op_info->op == OP_TYPE_vv) + return e.use_exact_insn (code_for_pred_ncopysign (e.vector_mode ())); + gcc_unreachable (); + } +}; + /* Implements vmfeq/vmfne/vmflt/vmfgt/vmfle/vmfge. */ template<rtx_code CODE> class fcmp : public function_base @@ -2031,7 +2045,7 @@ static CONSTEXPR const float_misc<UNSPEC_VFREC7> vfrec7_obj; static CONSTEXPR const binop<SMIN> vfmin_obj; static CONSTEXPR const binop<SMAX> vfmax_obj; static CONSTEXPR const float_misc<UNSPEC_VCOPYSIGN> vfsgnj_obj; -static CONSTEXPR const float_misc<UNSPEC_VNCOPYSIGN> vfsgnjn_obj; +static CONSTEXPR const vfsgnjn vfsgnjn_obj; static CONSTEXPR const float_misc<UNSPEC_VXORSIGN> vfsgnjx_obj; static CONSTEXPR const unop<NEG> vfneg_obj; static CONSTEXPR const unop<ABS> vfabs_obj; diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 6ca1c54c709..2c0c53c0c28 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -61,7 +61,6 @@ (define_c_enum "unspec" [ UNSPEC_VFCLASS UNSPEC_VCOPYSIGN - UNSPEC_VNCOPYSIGN UNSPEC_VXORSIGN UNSPEC_VFCVT @@ -1480,14 +1479,11 @@ (define_int_attr misc_op [(UNSPEC_VMSBF "sbf") (UNSPEC_VMSIF "sif") (UNSPEC_VMSO (define_int_attr float_insn_type [(UNSPEC_VFRSQRT7 "vfsqrt") (UNSPEC_VFREC7 "vfrecp")]) -(define_int_iterator VCOPYSIGNS [UNSPEC_VCOPYSIGN UNSPEC_VNCOPYSIGN UNSPEC_VXORSIGN]) +(define_int_iterator VCOPYSIGNS [UNSPEC_VCOPYSIGN UNSPEC_VXORSIGN]) -(define_int_attr copysign [(UNSPEC_VCOPYSIGN "copysign") - (UNSPEC_VNCOPYSIGN "ncopysign") - (UNSPEC_VXORSIGN "xorsign")]) +(define_int_attr copysign [(UNSPEC_VCOPYSIGN "copysign") (UNSPEC_VXORSIGN "xorsign")]) -(define_int_attr nx [(UNSPEC_VCOPYSIGN "") (UNSPEC_VNCOPYSIGN "n") - (UNSPEC_VXORSIGN "x")]) +(define_int_attr nx [(UNSPEC_VCOPYSIGN "") (UNSPEC_VXORSIGN "x")]) (define_int_attr ud [(UNSPEC_VSLIDEUP "up") (UNSPEC_VSLIDEDOWN "down") (UNSPEC_VSLIDE1UP "1up") (UNSPEC_VSLIDE1DOWN "1down") diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 884e7435cc2..aa81b9023d8 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -5820,6 +5820,27 @@ (define_insn "@pred_<copysign><mode>" [(set_attr "type" "vfsgnj") (set_attr "mode" "<MODE>")]) +(define_insn "@pred_ncopysign<mode>" + [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr") + (if_then_else:VF + (unspec:<VM> + [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") + (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") + (match_operand 6 "const_int_operand" " i, i, i, i") + (match_operand 7 "const_int_operand" " i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (neg:VF + (unspec:VF + [(match_operand:VF 3 "register_operand" " vr, vr, vr, vr") + (match_operand:VF 4 "register_operand" " vr, vr, vr, vr")] UNSPEC_VCOPYSIGN)) + (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))] + "TARGET_VECTOR" + "vfsgnjn.vv\t%0,%3,%4%p1" + [(set_attr "type" "vfsgnj") + (set_attr "mode" "<MODE>")]) + (define_insn "@pred_<copysign><mode>_scalar" [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr") (if_then_else:VF @@ -5841,6 +5862,28 @@ (define_insn "@pred_<copysign><mode>_scalar" [(set_attr "type" "vfsgnj") (set_attr "mode" "<MODE>")]) +(define_insn "@pred_ncopysign<mode>_scalar" + [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr") + (if_then_else:VF + (unspec:<VM> + [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") + (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") + (match_operand 6 "const_int_operand" " i, i, i, i") + (match_operand 7 "const_int_operand" " i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (neg:VF + (unspec:VF + [(match_operand:VF 3 "register_operand" " vr, vr, vr, vr") + (vec_duplicate:VF + (match_operand:<VEL> 4 "register_operand" " f, f, f, f"))] UNSPEC_VCOPYSIGN)) + (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))] + "TARGET_VECTOR" + "vfsgnjn.vf\t%0,%3,%4%p1" + [(set_attr "type" "vfsgnj") + (set_attr "mode" "<MODE>")]) + ;; ------------------------------------------------------------------------------- ;; ---- Predicated floating-point ternary operations ;; ------------------------------------------------------------------------------- diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-run.c new file mode 100644 index 00000000000..7a6d429c9a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-run.c @@ -0,0 +1,89 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */ + +#include "copysign-template.h" + +#include <assert.h> + +#define SZ 512 + +#define EPS 1e-6 + +#define RUN(TYPE,VAL) \ + TYPE a##TYPE[SZ]; \ + TYPE b##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + a##TYPE[i] = i; \ + b##TYPE[i] = (i & 1) ? VAL : -VAL; \ + } \ + copysign_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (a##TYPE[i] - ((i & 1) ? i : -i)) < EPS); \ + +#define RUN2(TYPE,VAL) \ + TYPE a2##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + a2##TYPE[i] = i; \ + copysigns_##TYPE (a2##TYPE, a2##TYPE, -VAL, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (a2##TYPE[i] + i) < EPS); \ + +#define RUN3(TYPE,VAL) \ + TYPE a3##TYPE[SZ]; \ + TYPE b3##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + a3##TYPE[i] = (i & 1) ? -i : i; \ + b3##TYPE[i] = (i & 1) ? VAL : -VAL; \ + } \ + xorsign_##TYPE (a3##TYPE, a3##TYPE, b3##TYPE, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (a3##TYPE[i] + i) < EPS); \ + +#define RUN4(TYPE,VAL) \ + TYPE a4##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + a4##TYPE[i] = -i; \ + xorsigns_##TYPE (a4##TYPE, a4##TYPE, -VAL, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (a4##TYPE[i] - i) < EPS); \ + +#define RUN5(TYPE,VAL) \ + TYPE a5##TYPE[SZ]; \ + TYPE b5##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + a5##TYPE[i] = i; \ + b5##TYPE[i] = (i & 1) ? VAL : -VAL; \ + } \ + ncopysign_##TYPE (a5##TYPE, a5##TYPE, b##TYPE, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (-a5##TYPE[i] - ((i & 1) ? i : -i)) < EPS); \ + +#define RUN6(TYPE,VAL) \ + TYPE a6##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + a6##TYPE[i] = i; \ + ncopysigns_##TYPE (a6##TYPE, a6##TYPE, -VAL, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (-a6##TYPE[i] + i) < EPS); \ + +#define RUN_ALL() \ + RUN(float, 5) \ + RUN(double, 6) \ + RUN2(float, 11) \ + RUN2(double, 12) \ + RUN3(float, 16) \ + RUN3(double, 18) \ + RUN4(float, 17) \ + RUN4(double, 19) \ + RUN5(float, 123) \ + RUN5(double, 523) \ + RUN6(float, 777) \ + RUN6(double, 877) \ + +int main () +{ + RUN_ALL() +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv32gcv.c new file mode 100644 index 00000000000..db29e37598a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv32gcv.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -O3 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */ + +#include "copysign-template.h" + +/* { dg-final { scan-assembler-times {\tvfsgnj\.vv} 6 } } */ +/* The vectorizer wraps scalar variants of copysign into vector constants which + expand cannot handle currently. Therefore only expect 3 instead of 6 + vfsgnjx.vv. */ +/* { dg-final { scan-assembler-times {\tvfsgnjx\.vv} 3 } } */ +/* { dg-final { scan-assembler-times {\tvfsgnjn\.vv} 6 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv64gcv.c new file mode 100644 index 00000000000..1c2504915cc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-rv64gcv.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -O3 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */ + +#include "copysign-template.h" + +/* { dg-final { scan-assembler-times {\tvfsgnj\.vv} 6 } } */ +/* The vectorizer wraps scalar variants of copysign into vector constants which + expand cannot handle currently. Therefore only expect 3 instead of 6 + vfsgnjx.vv. */ +/* { dg-final { scan-assembler-times {\tvfsgnjx\.vv} 3 } } */ +/* { dg-final { scan-assembler-times {\tvfsgnjn\.vv} 6 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-template.h new file mode 100644 index 00000000000..df2274fd3ef --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-template.h @@ -0,0 +1,78 @@ +#include <stdint-gcc.h> + +#define TEST_TYPE(TYPE, SUFFIX) \ + __attribute__((noipa)) \ + void copysign_##TYPE (TYPE *restrict dst, TYPE *restrict a, \ + TYPE *restrict b, int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = __builtin_copysign##SUFFIX (a[i], b[i]); \ + } + +#define TEST_TYPE2(TYPE, SUFFIX) \ + __attribute__((noipa)) \ + void copysigns_##TYPE (TYPE *restrict dst, TYPE *restrict a, \ + TYPE b, int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = __builtin_copysign##SUFFIX (a[i], b); \ + } + +#define TEST_TYPE3(TYPE, SUFFIX) \ + __attribute__((noipa)) \ + void xorsign_##TYPE (TYPE *restrict dst, TYPE *restrict a, \ + TYPE *restrict b, int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = a[i] * __builtin_copysign##SUFFIX (1.0, b[i]); \ + } + +#define TEST_TYPE4(TYPE, SUFFIX) \ + __attribute__((noipa)) \ + void xorsigns_##TYPE (TYPE *restrict dst, TYPE *restrict a, \ + TYPE b, int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = a[i] * __builtin_copysign##SUFFIX (1.0, b); \ + } + +#define TEST_TYPE5(TYPE, SUFFIX) \ + __attribute__((noipa)) \ + void ncopysign_##TYPE (TYPE *restrict dst, TYPE *restrict a, \ + TYPE *restrict b, int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = -__builtin_copysign##SUFFIX (a[i], b[i]); \ + } + +#define TEST_TYPE6(TYPE, SUFFIX) \ + __attribute__((noipa)) \ + void ncopysigns_##TYPE (TYPE *restrict dst, TYPE *restrict a, \ + TYPE b, int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = -__builtin_copysign##SUFFIX (a[i], b); \ + } + + +#define TEST_ALL() \ + TEST_TYPE(_Float16,f16) \ + TEST_TYPE(float,f) \ + TEST_TYPE(double,) \ + TEST_TYPE2(_Float16,f16) \ + TEST_TYPE2(float,f) \ + TEST_TYPE2(double,) \ + TEST_TYPE3(_Float16,f16) \ + TEST_TYPE3(float,f) \ + TEST_TYPE3(double,) \ + TEST_TYPE4(_Float16,f16) \ + TEST_TYPE4(float,f) \ + TEST_TYPE4(double,) \ + TEST_TYPE5(_Float16,f16) \ + TEST_TYPE5(float,f) \ + TEST_TYPE5(double,) \ + TEST_TYPE6(_Float16,f16) \ + TEST_TYPE6(float,f) \ + TEST_TYPE6(double,) \ + +TEST_ALL() diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-zvfh-run.c new file mode 100644 index 00000000000..7aaac9794f0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/copysign-zvfh-run.c @@ -0,0 +1,83 @@ +/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */ + +#include "copysign-template.h" + +#include <assert.h> + +#define SZ 512 + +#define EPS 1e-6 + +#define RUN(TYPE,VAL) \ + TYPE a##TYPE[SZ]; \ + TYPE b##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + a##TYPE[i] = i; \ + b##TYPE[i] = (i & 1) ? VAL : -VAL; \ + } \ + copysign_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (a##TYPE[i] - ((i & 1) ? i : -i)) < EPS); \ + +#define RUN2(TYPE,VAL) \ + TYPE a2##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + a2##TYPE[i] = i; \ + copysigns_##TYPE (a2##TYPE, a2##TYPE, -VAL, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (a2##TYPE[i] + i) < EPS); \ + +#define RUN3(TYPE,VAL) \ + TYPE a3##TYPE[SZ]; \ + TYPE b3##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + a3##TYPE[i] = (i & 1) ? -i : i; \ + b3##TYPE[i] = (i & 1) ? VAL : -VAL; \ + } \ + xorsign_##TYPE (a3##TYPE, a3##TYPE, b3##TYPE, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (a3##TYPE[i] + i) < EPS); \ + +#define RUN4(TYPE,VAL) \ + TYPE a4##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + a4##TYPE[i] = -i; \ + xorsigns_##TYPE (a4##TYPE, a4##TYPE, -VAL, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (a4##TYPE[i] - i) < EPS); \ + +#define RUN5(TYPE,VAL) \ + TYPE a5##TYPE[SZ]; \ + TYPE b5##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + a5##TYPE[i] = i; \ + b5##TYPE[i] = (i & 1) ? VAL : -VAL; \ + } \ + ncopysign_##TYPE (a5##TYPE, a5##TYPE, b##TYPE, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (-a5##TYPE[i] - ((i & 1) ? i : -i)) < EPS); \ + +#define RUN6(TYPE,VAL) \ + TYPE a6##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + a6##TYPE[i] = i; \ + ncopysigns_##TYPE (a6##TYPE, a6##TYPE, -VAL, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (__builtin_fabs (-a6##TYPE[i] + i) < EPS); \ + +#define RUN_ALL() \ + RUN(_Float16, 5) \ + RUN2(_Float16, 11) \ + RUN3(_Float16, 16) \ + RUN4(_Float16, 17) \ + RUN5(_Float16, 123) \ + RUN6(_Float16, 777) \ + +int main () +{ + RUN_ALL() +} -- 2.40.1