diff options
author | James Greenhalgh <james.greenhalgh@arm.com> | 2012-12-05 10:34:31 +0000 |
---|---|---|
committer | James Greenhalgh <jgreenhalgh@gcc.gnu.org> | 2012-12-05 10:34:31 +0000 |
commit | 42fc9a7f08f7762b2055e563eeecac81c794b457 (patch) | |
tree | 7add6443c2ec20e9136161c82953fe3d054b8ec3 | |
parent | be4c5193199667c1e167ad558f4c8a9504eeeda6 (diff) | |
download | gcc-42fc9a7f08f7762b2055e563eeecac81c794b457.zip gcc-42fc9a7f08f7762b2055e563eeecac81c794b457.tar.gz gcc-42fc9a7f08f7762b2055e563eeecac81c794b457.tar.bz2 |
[AARCH64] Add support for vectorizable standard math patterns.
gcc/
* config/aarch64/aarch64-builtins.c
(aarch64_builtin_vectorized_function): New.
* config/aarch64/aarch64-protos.h
(aarch64_builtin_vectorized_function): Declare.
* config/aarch64/aarch64-simd-builtins.def (frintz, frintp): Add.
(frintm, frinti, frintx, frinta, fcvtzs, fcvtzu): Likewise.
(fcvtas, fcvtau, fcvtps, fcvtpu, fcvtms, fcvtmu): Likewise.
* config/aarch64/aarch64-simd.md
(aarch64_frint_<frint_suffix><mode>): New.
(<frint_pattern><mode>2): Likewise.
(aarch64_fcvt<frint_suffix><su><mode>): Likewise.
(l<fcvt_pattern><su_optab><fcvt_target><VDQF:mode>2): Likewise.
* config/aarch64/aarch64.c (TARGET_VECTORIZE_BUILTINS): Define.
(TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION): Likewise.
* config/aarch64/aarch64.md
(btrunc<mode>2, ceil<mode>2, floor<mode>2)
(round<mode>2, rint<mode>2, nearbyint<mode>2): Consolidate as...
(<frint_pattern><mode>2): ...this.
(lceil<su_optab><mode><mode>2, lfloor<su_optab><mode><mode>2)
(lround<su_optab><mode><mode>2)
(lrint<su_optab><mode><mode>2): Consolidate as...
(l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2): ... this.
* config/aarch64/iterators.md (fcvt_target): New.
(FCVT_TARGET): Likewise.
(FRINT): Likewise.
(FCVT): Likewise.
(frint_pattern): Likewise.
(frint_suffix): Likewise.
(fcvt_pattern): Likewise.
gcc/testsuite/
* gcc.dg/vect/vect-rounding-btrunc.c: New test.
* gcc.dg/vect/vect-rounding-btruncf.c: Likewise.
* gcc.dg/vect/vect-rounding-ceil.c: Likewise.
* gcc.dg/vect/vect-rounding-ceilf.c: Likewise.
* gcc.dg/vect/vect-rounding-floor.c: Likewise.
* gcc.dg/vect/vect-rounding-floorf.c: Likewise.
* gcc.dg/vect/vect-rounding-lceil.c: Likewise.
* gcc.dg/vect/vect-rounding-lfloor.c: Likewise.
* gcc.dg/vect/vect-rounding-nearbyint.c: Likewise.
* gcc.dg/vect/vect-rounding-nearbyintf.c: Likewise.
* gcc.dg/vect/vect-rounding-round.c: Likewise.
* gcc.dg/vect/vect-rounding-roundf.c: Likewise.
* target-supports.exp
(check_effective_target_vect_call_btrunc): New.
(check_effective_target_vect_call_btruncf): Likewise.
(check_effective_target_vect_call_ceil): Likewise.
(check_effective_target_vect_call_ceilf): Likewise.
(check_effective_target_vect_call_floor): Likewise.
(check_effective_target_vect_call_floorf): Likewise.
(check_effective_target_vect_call_lceil): Likewise.
(check_effective_target_vect_call_lfloor): Likewise.
(check_effective_target_vect_call_nearbyint): Likewise.
(check_effective_target_vect_call_nearbyintf): Likewise.
(check_effective_target_vect_call_round): Likewise.
(check_effective_target_vect_call_roundf): Likewise.
From-SVN: r194197
22 files changed, 654 insertions, 102 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5bbe08b..aa10fd3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,35 @@ +2012-12-05 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/aarch64-builtins.c + (aarch64_builtin_vectorized_function): New. + * config/aarch64/aarch64-protos.h + (aarch64_builtin_vectorized_function): Declare. + * config/aarch64/aarch64-simd-builtins.def (frintz, frintp): Add. + (frintm, frinti, frintx, frinta, fcvtzs, fcvtzu): Likewise. + (fcvtas, fcvtau, fcvtps, fcvtpu, fcvtms, fcvtmu): Likewise. + * config/aarch64/aarch64-simd.md + (aarch64_frint_<frint_suffix><mode>): New. + (<frint_pattern><mode>2): Likewise. + (aarch64_fcvt<frint_suffix><su><mode>): Likewise. + (l<fcvt_pattern><su_optab><fcvt_target><VDQF:mode>2): Likewise. + * config/aarch64/aarch64.c (TARGET_VECTORIZE_BUILTINS): Define. + (TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION): Likewise. + * config/aarch64/aarch64.md + (btrunc<mode>2, ceil<mode>2, floor<mode>2) + (round<mode>2, rint<mode>2, nearbyint<mode>2): Consolidate as... + (<frint_pattern><mode>2): ...this. + (lceil<su_optab><mode><mode>2, lfloor<su_optab><mode><mode>2) + (lround<su_optab><mode><mode>2) + (lrint<su_optab><mode><mode>2): Consolidate as... + (l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2): ... this. + * config/aarch64/iterators.md (fcvt_target): New. + (FCVT_TARGET): Likewise. + (FRINT): Likewise. + (FCVT): Likewise. + (frint_pattern): Likewise. + (frint_suffix): Likewise. + (fcvt_pattern): Likewise. + 2012-12-05 Steven Bosscher <steven@gcc.gnu.org> * passes.c (pass_init_dump_file): Only open a clean graph dump file if diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c index 2cdda0f..a683afd 100644 --- a/gcc/config/aarch64/aarch64-builtins.c +++ b/gcc/config/aarch64/aarch64-builtins.c @@ -1221,3 +1221,70 @@ aarch64_expand_builtin (tree exp, return NULL_RTX; } + +tree +aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) +{ + enum machine_mode in_mode, out_mode; + int in_n, out_n; + + if (TREE_CODE (type_out) != VECTOR_TYPE + || TREE_CODE (type_in) != VECTOR_TYPE) + return NULL_TREE; + + out_mode = TYPE_MODE (TREE_TYPE (type_out)); + out_n = TYPE_VECTOR_SUBPARTS (type_out); + in_mode = TYPE_MODE (TREE_TYPE (type_in)); + in_n = TYPE_VECTOR_SUBPARTS (type_in); + +#undef AARCH64_CHECK_BUILTIN_MODE +#define AARCH64_CHECK_BUILTIN_MODE(C, N) 1 +#define AARCH64_FIND_FRINT_VARIANT(N) \ + (AARCH64_CHECK_BUILTIN_MODE (2, D) \ + ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_##N##v2df] \ + : (AARCH64_CHECK_BUILTIN_MODE (4, S) \ + ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_##N##v4sf] \ + : (AARCH64_CHECK_BUILTIN_MODE (2, S) \ + ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_##N##v2sf] \ + : NULL_TREE))) + if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + { + enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); + switch (fn) + { +#undef AARCH64_CHECK_BUILTIN_MODE +#define AARCH64_CHECK_BUILTIN_MODE(C, N) \ + (out_mode == N##Fmode && out_n == C \ + && in_mode == N##Fmode && in_n == C) + case BUILT_IN_FLOOR: + case BUILT_IN_FLOORF: + return AARCH64_FIND_FRINT_VARIANT (frintm); + case BUILT_IN_CEIL: + case BUILT_IN_CEILF: + return AARCH64_FIND_FRINT_VARIANT (frintp); + case BUILT_IN_TRUNC: + case BUILT_IN_TRUNCF: + return AARCH64_FIND_FRINT_VARIANT (frintz); + case BUILT_IN_ROUND: + case BUILT_IN_ROUNDF: + return AARCH64_FIND_FRINT_VARIANT (frinta); + case BUILT_IN_NEARBYINT: + case BUILT_IN_NEARBYINTF: + return AARCH64_FIND_FRINT_VARIANT (frinti); +#undef AARCH64_CHECK_BUILTIN_MODE +#define AARCH64_CHECK_BUILTIN_MODE(C, N) \ + (out_mode == N##Imode && out_n == C \ + && in_mode == N##Fmode && in_n == C) + case BUILT_IN_LFLOOR: + return AARCH64_FIND_FRINT_VARIANT (fcvtms); + case BUILT_IN_LCEIL: + return AARCH64_FIND_FRINT_VARIANT (fcvtps); + default: + return NULL_TREE; + } + } + + return NULL_TREE; +} +#undef AARCH64_CHECK_BUILTIN_MODE +#undef AARCH64_FIND_FRINT_VARIANT diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index ab84257..2110970 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -236,4 +236,9 @@ rtx aarch64_expand_builtin (tree exp, int ignore ATTRIBUTE_UNUSED); tree aarch64_builtin_decl (unsigned, bool ATTRIBUTE_UNUSED); +tree +aarch64_builtin_vectorized_function (tree fndecl, + tree type_out, + tree type_in); + #endif /* GCC_AARCH64_PROTOS_H */ diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index 2e3c4e1..b344120 100644 --- a/gcc/config/aarch64/aarch64-simd-builtins.def +++ b/gcc/config/aarch64/aarch64-simd-builtins.def @@ -206,3 +206,21 @@ BUILTIN_VDQ_BHSI (BINOP, smin) BUILTIN_VDQ_BHSI (BINOP, umax) BUILTIN_VDQ_BHSI (BINOP, umin) + + /* Implemented by aarch64_frint<frint_suffix><mode>. */ + BUILTIN_VDQF (UNOP, frintz) + BUILTIN_VDQF (UNOP, frintp) + BUILTIN_VDQF (UNOP, frintm) + BUILTIN_VDQF (UNOP, frinti) + BUILTIN_VDQF (UNOP, frintx) + BUILTIN_VDQF (UNOP, frinta) + + /* Implemented by aarch64_fcvt<frint_suffix><su><mode>. */ + BUILTIN_VDQF (UNOP, fcvtzs) + BUILTIN_VDQF (UNOP, fcvtzu) + BUILTIN_VDQF (UNOP, fcvtas) + BUILTIN_VDQF (UNOP, fcvtau) + BUILTIN_VDQF (UNOP, fcvtps) + BUILTIN_VDQF (UNOP, fcvtpu) + BUILTIN_VDQF (UNOP, fcvtms) + BUILTIN_VDQF (UNOP, fcvtmu) diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index b3d01c1..8c9ceac 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1240,6 +1240,46 @@ (set_attr "simd_mode" "<MODE>")] ) +(define_insn "aarch64_frint<frint_suffix><mode>" + [(set (match_operand:VDQF 0 "register_operand" "=w") + (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")] + FRINT))] + "TARGET_SIMD" + "frint<frint_suffix>\\t%0.<Vtype>, %1.<Vtype>" + [(set_attr "simd_type" "simd_frint") + (set_attr "simd_mode" "<MODE>")] +) + +;; Vector versions of the floating-point frint patterns. +;; Expands to btrunc, ceil, floor, nearbyint, rint, round. +(define_expand "<frint_pattern><mode>2" + [(set (match_operand:VDQF 0 "register_operand") + (unspec:VDQF [(match_operand:VDQF 1 "register_operand")] + FRINT))] + "TARGET_SIMD" + {}) + +(define_insn "aarch64_fcvt<frint_suffix><su><mode>" + [(set (match_operand:<FCVT_TARGET> 0 "register_operand" "=w") + (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET> + [(match_operand:VDQF 1 "register_operand" "w")] + FCVT)))] + "TARGET_SIMD" + "fcvt<frint_suffix><su>\\t%0.<Vtype>, %1.<Vtype>" + [(set_attr "simd_type" "simd_fcvti") + (set_attr "simd_mode" "<MODE>")] +) + +;; Vector versions of the fcvt standard patterns. +;; Expands to lbtrunc, lround, lceil, lfloor +(define_expand "l<fcvt_pattern><su_optab><fcvt_target><VDQF:mode>2" + [(set (match_operand:<FCVT_TARGET> 0 "register_operand") + (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET> + [(match_operand:VDQF 1 "register_operand")] + FCVT)))] + "TARGET_SIMD" + {}) + (define_insn "aarch64_vmls<mode>" [(set (match_operand:VDQF 0 "register_operand" "=w") (minus:VDQF (match_operand:VDQF 1 "register_operand" "0") diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 445cd4f..971e71f 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -6879,6 +6879,13 @@ aarch64_c_mode_for_suffix (char suffix) #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE aarch64_preferred_simd_mode +#undef TARGET_VECTORIZE_BUILTINS +#define TARGET_VECTORIZE_BUILTINS + +#undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION +#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \ + aarch64_builtin_vectorized_function + /* Section anchor support. */ #undef TARGET_MIN_ANCHOR_OFFSET diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 17f024f..b59d53d 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -2325,117 +2325,27 @@ ;; Floating-point intrinsics ;; ------------------------------------------------------------------- -;; trunc - nothrow +;; frint floating-point round to integral standard patterns. +;; Expands to btrunc, ceil, floor, nearbyint, rint, round. -(define_insn "btrunc<mode>2" +(define_insn "<frint_pattern><mode>2" [(set (match_operand:GPF 0 "register_operand" "=w") - (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] - UNSPEC_FRINTZ))] + (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] + FRINT))] "TARGET_FLOAT" - "frintz\\t%<s>0, %<s>1" + "frint<frint_suffix>\\t%<s>0, %<s>1" [(set_attr "v8type" "frint") (set_attr "mode" "<MODE>")] ) -(define_insn "*lbtrunc<su_optab><GPF:mode><GPI:mode>2" +;; frcvt floating-point round to integer and convert standard patterns. +;; Expands to lbtrunc, lceil, lfloor, lround. +(define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2" [(set (match_operand:GPI 0 "register_operand" "=r") - (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] - UNSPEC_FRINTZ)))] + (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] + FCVT)))] "TARGET_FLOAT" - "fcvtz<su>\\t%<GPI:w>0, %<GPF:s>1" - [(set_attr "v8type" "fcvtf2i") - (set_attr "mode" "<GPF:MODE>") - (set_attr "mode2" "<GPI:MODE>")] -) - -;; ceil - nothrow - -(define_insn "ceil<mode>2" - [(set (match_operand:GPF 0 "register_operand" "=w") - (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] - UNSPEC_FRINTP))] - "TARGET_FLOAT" - "frintp\\t%<s>0, %<s>1" - [(set_attr "v8type" "frint") - (set_attr "mode" "<MODE>")] -) - -(define_insn "lceil<su_optab><GPF:mode><GPI:mode>2" - [(set (match_operand:GPI 0 "register_operand" "=r") - (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] - UNSPEC_FRINTP)))] - "TARGET_FLOAT" - "fcvtp<su>\\t%<GPI:w>0, %<GPF:s>1" - [(set_attr "v8type" "fcvtf2i") - (set_attr "mode" "<GPF:MODE>") - (set_attr "mode2" "<GPI:MODE>")] -) - -;; floor - nothrow - -(define_insn "floor<mode>2" - [(set (match_operand:GPF 0 "register_operand" "=w") - (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] - UNSPEC_FRINTM))] - "TARGET_FLOAT" - "frintm\\t%<s>0, %<s>1" - [(set_attr "v8type" "frint") - (set_attr "mode" "<MODE>")] -) - -(define_insn "lfloor<su_optab><GPF:mode><GPI:mode>2" - [(set (match_operand:GPI 0 "register_operand" "=r") - (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] - UNSPEC_FRINTM)))] - "TARGET_FLOAT" - "fcvtm<su>\\t%<GPI:w>0, %<GPF:s>1" - [(set_attr "v8type" "fcvtf2i") - (set_attr "mode" "<GPF:MODE>") - (set_attr "mode2" "<GPI:MODE>")] -) - -;; nearbyint - nothrow - -(define_insn "nearbyint<mode>2" - [(set (match_operand:GPF 0 "register_operand" "=w") - (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] - UNSPEC_FRINTI))] - "TARGET_FLOAT" - "frinti\\t%<s>0, %<s>1" - [(set_attr "v8type" "frint") - (set_attr "mode" "<MODE>")] -) - -;; rint - -(define_insn "rint<mode>2" - [(set (match_operand:GPF 0 "register_operand" "=w") - (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] - UNSPEC_FRINTX))] - "TARGET_FLOAT" - "frintx\\t%<s>0, %<s>1" - [(set_attr "v8type" "frint") - (set_attr "mode" "<MODE>")] -) - -;; round - nothrow - -(define_insn "round<mode>2" - [(set (match_operand:GPF 0 "register_operand" "=w") - (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] - UNSPEC_FRINTA))] - "TARGET_FLOAT" - "frinta\\t%<s>0, %<s>1" - [(set_attr "v8type" "frint") - (set_attr "mode" "<MODE>")] -) - -(define_insn "lround<su_optab><GPF:mode><GPI:mode>2" - [(set (match_operand:GPI 0 "register_operand" "=r") - (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] - UNSPEC_FRINTA)))] - "TARGET_FLOAT" - "fcvta<su>\\t%<GPI:w>0, %<GPF:s>1" + "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1" [(set_attr "v8type" "fcvtf2i") (set_attr "mode" "<GPF:MODE>") (set_attr "mode2" "<GPI:MODE>")] diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 7a1cdc8..31bc977 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -453,6 +453,9 @@ (define_mode_attr atomic_sfx [(QI "b") (HI "h") (SI "") (DI "")]) +(define_mode_attr fcvt_target [(V2DF "v2di") (V4SF "v4si") (V2SF "v2si")]) +(define_mode_attr FCVT_TARGET [(V2DF "V2DI") (V4SF "V4SI") (V2SF "V2SI")]) + ;; ------------------------------------------------------------------- ;; Code Iterators ;; ------------------------------------------------------------------- @@ -647,6 +650,12 @@ (define_int_iterator VCMP_U [UNSPEC_CMHS UNSPEC_CMHI UNSPEC_CMTST]) +(define_int_iterator FRINT [UNSPEC_FRINTZ UNSPEC_FRINTP UNSPEC_FRINTM + UNSPEC_FRINTI UNSPEC_FRINTX UNSPEC_FRINTA]) + +(define_int_iterator FCVT [UNSPEC_FRINTZ UNSPEC_FRINTP UNSPEC_FRINTM + UNSPEC_FRINTA]) + ;; ------------------------------------------------------------------- ;; Int Iterators Attributes. ;; ------------------------------------------------------------------- @@ -729,3 +738,19 @@ (define_int_attr offsetlr [(UNSPEC_SSLI "1") (UNSPEC_USLI "1") (UNSPEC_SSRI "0") (UNSPEC_USRI "0")]) +;; Standard pattern names for floating-point rounding instructions. +(define_int_attr frint_pattern [(UNSPEC_FRINTZ "btrunc") + (UNSPEC_FRINTP "ceil") + (UNSPEC_FRINTM "floor") + (UNSPEC_FRINTI "nearbyint") + (UNSPEC_FRINTX "rint") + (UNSPEC_FRINTA "round")]) + +;; frint suffix for floating-point rounding instructions. +(define_int_attr frint_suffix [(UNSPEC_FRINTZ "z") (UNSPEC_FRINTP "p") + (UNSPEC_FRINTM "m") (UNSPEC_FRINTI "i") + (UNSPEC_FRINTX "x") (UNSPEC_FRINTA "a")]) + +(define_int_attr fcvt_pattern [(UNSPEC_FRINTZ "btrunc") (UNSPEC_FRINTA "round") + (UNSPEC_FRINTP "ceil") (UNSPEC_FRINTM "floor")]) + diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5c363d0..0bba403e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,31 @@ +2012-12-05 James Greenhalgh <james.greenhalgh@arm.com> + + * gcc.dg/vect/vect-rounding-btrunc.c: New test. + * gcc.dg/vect/vect-rounding-btruncf.c: Likewise. + * gcc.dg/vect/vect-rounding-ceil.c: Likewise. + * gcc.dg/vect/vect-rounding-ceilf.c: Likewise. + * gcc.dg/vect/vect-rounding-floor.c: Likewise. + * gcc.dg/vect/vect-rounding-floorf.c: Likewise. + * gcc.dg/vect/vect-rounding-lceil.c: Likewise. + * gcc.dg/vect/vect-rounding-lfloor.c: Likewise. + * gcc.dg/vect/vect-rounding-nearbyint.c: Likewise. + * gcc.dg/vect/vect-rounding-nearbyintf.c: Likewise. + * gcc.dg/vect/vect-rounding-round.c: Likewise. + * gcc.dg/vect/vect-rounding-roundf.c: Likewise. + * target-supports.exp + (check_effective_target_vect_call_btrunc): New. + (check_effective_target_vect_call_btruncf): Likewise. + (check_effective_target_vect_call_ceil): Likewise. + (check_effective_target_vect_call_ceilf): Likewise. + (check_effective_target_vect_call_floor): Likewise. + (check_effective_target_vect_call_floorf): Likewise. + (check_effective_target_vect_call_lceil): Likewise. + (check_effective_target_vect_call_lfloor): Likewise. + (check_effective_target_vect_call_nearbyint): Likewise. + (check_effective_target_vect_call_nearbyintf): Likewise. + (check_effective_target_vect_call_round): Likewise. + (check_effective_target_vect_call_roundf): Likewise. + 2012-12-05 Richard Biener <rguenther@suse.de> PR tree-optimization/51238 diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-btrunc.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-btrunc.c new file mode 100644 index 0000000..7432fe7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-btrunc.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ +/* { dg-require-effective-target vect_call_btrunc } */ + +#define N 32 + +void +foo (double *output, double *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_trunc (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_btrunc } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-btruncf.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-btruncf.c new file mode 100644 index 0000000..0835e1b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-btruncf.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_call_btruncf } */ + +#define N 32 + +void +foo (float *output, float *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_truncf (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_btruncf } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-ceil.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-ceil.c new file mode 100644 index 0000000..a430690 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-ceil.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ +/* { dg-require-effective-target vect_call_ceil } */ + +#define N 32 + +void +foo (double *output, double *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_ceil (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_ceil } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-ceilf.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-ceilf.c new file mode 100644 index 0000000..4d00924 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-ceilf.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_call_ceilf } */ + +#define N 32 + +void +foo (float *output, float *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_ceilf (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_ceilf } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-floor.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-floor.c new file mode 100644 index 0000000..8f1c9ec --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-floor.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ +/* { dg-require-effective-target vect_call_floor } */ + +#define N 32 + +void +foo (double *output, double *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_floor (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_floor } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-floorf.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-floorf.c new file mode 100644 index 0000000..a68c2ec --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-floorf.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_call_floorf } */ + +#define N 32 + +void +foo (float *output, float *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_floorf (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_floorf } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-lceil.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-lceil.c new file mode 100644 index 0000000..b4ed236 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-lceil.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ +/* { dg-require-effective-target vect_call_lceil } */ + +#define N 32 + +void +foo (long *output, double *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_lceil (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_lceil } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-lfloor.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-lfloor.c new file mode 100644 index 0000000..5a36631 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-lfloor.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ +/* { dg-require-effective-target vect_call_lfloor } */ + +#define N 32 + +void +foo (long *output, double *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_lfloor (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_lfloor } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-nearbyint.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-nearbyint.c new file mode 100644 index 0000000..572dbd3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-nearbyint.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ +/* { dg-require-effective-target vect_call_nearbyint } */ + +#define N 32 + +void +foo (double *output, double *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_nearbyint (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_nearbyint } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-nearbyintf.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-nearbyintf.c new file mode 100644 index 0000000..73ca7de --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-nearbyintf.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_call_nearbyintf } */ + +#define N 32 + +void +foo (float *output, float *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_nearbyintf (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_nearbyintf } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-round.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-round.c new file mode 100644 index 0000000..c298bbb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-round.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ +/* { dg-require-effective-target vect_call_round } */ + +#define N 32 + +void +foo (double *output, double *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_round (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_round } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-rounding-roundf.c b/gcc/testsuite/gcc.dg/vect/vect-rounding-roundf.c new file mode 100644 index 0000000..362b9d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-rounding-roundf.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_call_roundf } */ + +#define N 32 + +void +foo (float *output, float *input) +{ + int i = 0; + /* Vectorizable. */ + for (i = 0; i < N; i++) + output[i] = __builtin_roundf (input[i]); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_call_roundf } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 5935346..59d854f 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3925,6 +3925,222 @@ proc check_effective_target_vect_call_lrint { } { return $et_vect_call_lrint } +# Return 1 if the target supports vector btrunc calls. + +proc check_effective_target_vect_call_btrunc { } { + global et_vect_call_btrunc_saved + + if [info exists et_vect_call_btrunc_saved] { + verbose "check_effective_target_vect_call_btrunc: using cached result" 2 + } else { + set et_vect_call_btrunc_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_btrunc_saved 1 + } + } + + verbose "check_effective_target_vect_call_btrunc: returning $et_vect_call_btrunc_saved" 2 + return $et_vect_call_btrunc_saved +} + +# Return 1 if the target supports vector btruncf calls. + +proc check_effective_target_vect_call_btruncf { } { + global et_vect_call_btruncf_saved + + if [info exists et_vect_call_btruncf_saved] { + verbose "check_effective_target_vect_call_btruncf: using cached result" 2 + } else { + set et_vect_call_btruncf_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_btruncf_saved 1 + } + } + + verbose "check_effective_target_vect_call_btruncf: returning $et_vect_call_btruncf_saved" 2 + return $et_vect_call_btruncf_saved +} + +# Return 1 if the target supports vector ceil calls. + +proc check_effective_target_vect_call_ceil { } { + global et_vect_call_ceil_saved + + if [info exists et_vect_call_ceil_saved] { + verbose "check_effective_target_vect_call_ceil: using cached result" 2 + } else { + set et_vect_call_ceil_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_ceil_saved 1 + } + } + + verbose "check_effective_target_vect_call_ceil: returning $et_vect_call_ceil_saved" 2 + return $et_vect_call_ceil_saved +} + +# Return 1 if the target supports vector ceilf calls. + +proc check_effective_target_vect_call_ceilf { } { + global et_vect_call_ceilf_saved + + if [info exists et_vect_call_ceilf_saved] { + verbose "check_effective_target_vect_call_ceilf: using cached result" 2 + } else { + set et_vect_call_ceilf_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_ceilf_saved 1 + } + } + + verbose "check_effective_target_vect_call_ceilf: returning $et_vect_call_ceilf_saved" 2 + return $et_vect_call_ceilf_saved +} + +# Return 1 if the target supports vector floor calls. + +proc check_effective_target_vect_call_floor { } { + global et_vect_call_floor_saved + + if [info exists et_vect_call_floor_saved] { + verbose "check_effective_target_vect_call_floor: using cached result" 2 + } else { + set et_vect_call_floor_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_floor_saved 1 + } + } + + verbose "check_effective_target_vect_call_floor: returning $et_vect_call_floor_saved" 2 + return $et_vect_call_floor_saved +} + +# Return 1 if the target supports vector floorf calls. + +proc check_effective_target_vect_call_floorf { } { + global et_vect_call_floorf_saved + + if [info exists et_vect_call_floorf_saved] { + verbose "check_effective_target_vect_call_floorf: using cached result" 2 + } else { + set et_vect_call_floorf_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_floorf_saved 1 + } + } + + verbose "check_effective_target_vect_call_floorf: returning $et_vect_call_floorf_saved" 2 + return $et_vect_call_floorf_saved +} + +# Return 1 if the target supports vector lceil calls. + +proc check_effective_target_vect_call_lceil { } { + global et_vect_call_lceil_saved + + if [info exists et_vect_call_lceil_saved] { + verbose "check_effective_target_vect_call_lceil: using cached result" 2 + } else { + set et_vect_call_lceil_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_lceil_saved 1 + } + } + + verbose "check_effective_target_vect_call_lceil: returning $et_vect_call_lceil_saved" 2 + return $et_vect_call_lceil_saved +} + +# Return 1 if the target supports vector lfloor calls. + +proc check_effective_target_vect_call_lfloor { } { + global et_vect_call_lfloor_saved + + if [info exists et_vect_call_lfloor_saved] { + verbose "check_effective_target_vect_call_lfloor: using cached result" 2 + } else { + set et_vect_call_lfloor_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_lfloor_saved 1 + } + } + + verbose "check_effective_target_vect_call_lfloor: returning $et_vect_call_lfloor_saved" 2 + return $et_vect_call_lfloor_saved +} + +# Return 1 if the target supports vector nearbyint calls. + +proc check_effective_target_vect_call_nearbyint { } { + global et_vect_call_nearbyint_saved + + if [info exists et_vect_call_nearbyint_saved] { + verbose "check_effective_target_vect_call_nearbyint: using cached result" 2 + } else { + set et_vect_call_nearbyint_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_nearbyint_saved 1 + } + } + + verbose "check_effective_target_vect_call_nearbyint: returning $et_vect_call_nearbyint_saved" 2 + return $et_vect_call_nearbyint_saved +} + +# Return 1 if the target supports vector nearbyintf calls. + +proc check_effective_target_vect_call_nearbyintf { } { + global et_vect_call_nearbyintf_saved + + if [info exists et_vect_call_nearbyintf_saved] { + verbose "check_effective_target_vect_call_nearbyintf: using cached result" 2 + } else { + set et_vect_call_nearbyintf_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_nearbyintf_saved 1 + } + } + + verbose "check_effective_target_vect_call_nearbyintf: returning $et_vect_call_nearbyintf_saved" 2 + return $et_vect_call_nearbyintf_saved +} + +# Return 1 if the target supports vector round calls. + +proc check_effective_target_vect_call_round { } { + global et_vect_call_round_saved + + if [info exists et_vect_call_round_saved] { + verbose "check_effective_target_vect_call_round: using cached result" 2 + } else { + set et_vect_call_round_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_round_saved 1 + } + } + + verbose "check_effective_target_vect_call_round: returning $et_vect_call_round_saved" 2 + return $et_vect_call_round_saved +} + +# Return 1 if the target supports vector roundf calls. + +proc check_effective_target_vect_call_roundf { } { + global et_vect_call_roundf_saved + + if [info exists et_vect_call_roundf_saved] { + verbose "check_effective_target_vect_call_roundf: using cached result" 2 + } else { + set et_vect_call_roundf_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_call_roundf_saved 1 + } + } + + verbose "check_effective_target_vect_call_roundf: returning $et_vect_call_roundf_saved" 2 + return $et_vect_call_roundf_saved +} + # Return 1 if the target supports section-anchors proc check_effective_target_section_anchors { } { |