Implement sqrshr, sqshl, srshr, uqrshl, uqshl and urshr using the new MVE builtins framework.
The patch fixes a probable copy/paste typo in mve_sqshl_si and mve_srshr_si: operand 1 should have mode SI, and not DI. gcc/ChangeLog: * config/arm/arm-mve-builtins-base.cc (enum which_scalar_shift): Add ss_SQRSHR, ss_SQSHL, ss_SRSHR, ss_UQRSHL, ss_UQSHL, and ss_URSHR. (mve_function_scalar_shift): Add suport for ss_SQRSHR, ss_SQSHL, ss_SRSHR, ss_UQRSHL, ss_UQSHL, and ss_URSHR. (sqrshr, sqshl, srshr, uqrshl, uqshl, urshr): New. * config/arm/arm-mve-builtins-base.def (sqrshr, sqshl, srshr) (uqrshl, uqshl, urshr): New. * config/arm/arm-mve-builtins-base.h (sqrshr, sqshl, srshr) (uqrshl, uqshl, urshr): New. * config/arm/arm-mve-builtins-shapes.cc (scalar_s32_shift): New. (scalar_s32_shift_imm): New. (scalar_u32_shift): New. (scalar_u32_shift_imm): New. * config/arm/arm-mve-builtins-shapes.h (scalar_s32_shift): New. (scalar_s32_shift_imm): New. (scalar_u32_shift): New. (scalar_u32_shift_imm): New. * config/arm/arm_mve.h (sqrshr): Delete. (sqshl): Delete. (srshr): Delete. (uqrshl): Delete. (uqshl): Delete. (urshr): Delete. (__arm_uqrshl): Delete. (__arm_sqrshr): Delete. (__arm_uqshl): Delete. (__arm_urshr): Delete. (__arm_sqshl): Delete. (__arm_srshr): Delete. * config/arm/mve.md (mve_sqshl_si, mve_srshr_si): Fix mode of operand 1. gcc/testsuite/ChangeLog: * gcc.target/arm/mve/intrinsics/sqshl_check_shift.c: New test. * gcc.target/arm/mve/intrinsics/srshr_check_shift.c: New test. * gcc.target/arm/mve/intrinsics/uqshl_check_shift.c: New test. * gcc.target/arm/mve/intrinsics/urshr_check_shift.c: New test. --- gcc/config/arm/arm-mve-builtins-base.cc | 36 +++++++++ gcc/config/arm/arm-mve-builtins-base.def | 6 ++ gcc/config/arm/arm-mve-builtins-base.h | 6 ++ gcc/config/arm/arm-mve-builtins-shapes.cc | 76 +++++++++++++++++++ gcc/config/arm/arm-mve-builtins-shapes.h | 4 + gcc/config/arm/arm_mve.h | 48 ------------ gcc/config/arm/mve.md | 4 +- .../arm/mve/intrinsics/sqshl_check_shift.c | 24 ++++++ .../arm/mve/intrinsics/srshr_check_shift.c | 24 ++++++ .../arm/mve/intrinsics/uqshl_check_shift.c | 24 ++++++ .../arm/mve/intrinsics/urshr_check_shift.c | 24 ++++++ 11 files changed, 226 insertions(+), 50 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl_check_shift.c create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr_check_shift.c create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl_check_shift.c create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr_check_shift.c diff --git a/gcc/config/arm/arm-mve-builtins-base.cc b/gcc/config/arm/arm-mve-builtins-base.cc index c98d4bea2e5..a5b1706a6c9 100644 --- a/gcc/config/arm/arm-mve-builtins-base.cc +++ b/gcc/config/arm/arm-mve-builtins-base.cc @@ -1246,13 +1246,19 @@ public: enum which_scalar_shift { ss_ASRL, ss_LSLL, + ss_SQRSHR, ss_SQRSHRL, ss_SQRSHRL_SAT48, + ss_SQSHL, ss_SQSHLL, + ss_SRSHR, ss_SRSHRL, + ss_UQRSHL, ss_UQRSHLL, ss_UQRSHLL_SAT48, + ss_UQSHL, ss_UQSHLL, + ss_URSHR, ss_URSHRL }; @@ -1282,6 +1288,10 @@ public: code = CODE_FOR_mve_lsll; break; + case ss_SQRSHR: + code = CODE_FOR_mve_sqrshr_si; + break; + case ss_SQRSHRL: code = code_for_mve_sqrshrl_sat_di (SQRSHRL_64); break; @@ -1290,6 +1300,18 @@ public: code = code_for_mve_sqrshrl_sat_di (SQRSHRL_48); break; + case ss_SQSHL: + code = CODE_FOR_mve_sqshl_si; + break; + + case ss_SRSHR: + code = CODE_FOR_mve_srshr_si; + break; + + case ss_UQRSHL: + code = CODE_FOR_mve_uqrshl_si; + break; + case ss_SQSHLL: code = CODE_FOR_mve_sqshll_di; break; @@ -1306,10 +1328,18 @@ public: code = code_for_mve_uqrshll_sat_di (UQRSHLL_48); break; + case ss_UQSHL: + code = CODE_FOR_mve_uqshl_si; + break; + case ss_UQSHLL: code = CODE_FOR_mve_uqshll_di; break; + case ss_URSHR: + code = CODE_FOR_mve_urshr_si; + break; + case ss_URSHRL: code = CODE_FOR_mve_urshrl_di; break; @@ -1491,13 +1521,19 @@ namespace arm_mve { FUNCTION (asrl, mve_function_scalar_shift, (ss_ASRL)) FUNCTION (lsll, mve_function_scalar_shift, (ss_LSLL)) +FUNCTION (sqrshr, mve_function_scalar_shift, (ss_SQRSHR)) FUNCTION (sqrshrl, mve_function_scalar_shift, (ss_SQRSHRL)) FUNCTION (sqrshrl_sat48, mve_function_scalar_shift, (ss_SQRSHRL_SAT48)) +FUNCTION (sqshl, mve_function_scalar_shift, (ss_SQSHL)) FUNCTION (sqshll, mve_function_scalar_shift, (ss_SQSHLL)) +FUNCTION (srshr, mve_function_scalar_shift, (ss_SRSHR)) FUNCTION (srshrl, mve_function_scalar_shift, (ss_SRSHRL)) +FUNCTION (uqrshl, mve_function_scalar_shift, (ss_UQRSHL)) FUNCTION (uqrshll, mve_function_scalar_shift, (ss_UQRSHLL)) FUNCTION (uqrshll_sat48, mve_function_scalar_shift, (ss_UQRSHLL_SAT48)) +FUNCTION (uqshl, mve_function_scalar_shift, (ss_UQSHL)) FUNCTION (uqshll, mve_function_scalar_shift, (ss_UQSHLL)) +FUNCTION (urshr, mve_function_scalar_shift, (ss_URSHR)) FUNCTION (urshrl, mve_function_scalar_shift, (ss_URSHRL)) FUNCTION_PRED_P_S_U (vabavq, VABAVQ) FUNCTION_WITHOUT_N (vabdq, VABDQ) diff --git a/gcc/config/arm/arm-mve-builtins-base.def b/gcc/config/arm/arm-mve-builtins-base.def index f46ce835596..9b9603e87b0 100644 --- a/gcc/config/arm/arm-mve-builtins-base.def +++ b/gcc/config/arm/arm-mve-builtins-base.def @@ -20,13 +20,19 @@ #define REQUIRES_FLOAT false DEF_MVE_FUNCTION (asrl, scalar_s64_shift, none, none) DEF_MVE_FUNCTION (lsll, scalar_u64_shift, none, none) +DEF_MVE_FUNCTION (sqrshr, scalar_s32_shift, none, none) DEF_MVE_FUNCTION (sqrshrl, scalar_s64_shift, none, none) DEF_MVE_FUNCTION (sqrshrl_sat48, scalar_s64_shift, none, none) +DEF_MVE_FUNCTION (sqshl, scalar_s32_shift_imm, none, none) DEF_MVE_FUNCTION (sqshll, scalar_s64_shift_imm, none, none) +DEF_MVE_FUNCTION (srshr, scalar_s32_shift_imm, none, none) DEF_MVE_FUNCTION (srshrl, scalar_s64_shift_imm, none, none) +DEF_MVE_FUNCTION (uqrshl, scalar_u32_shift, none, none) DEF_MVE_FUNCTION (uqrshll, scalar_u64_shift, none, none) DEF_MVE_FUNCTION (uqrshll_sat48, scalar_u64_shift, none, none) +DEF_MVE_FUNCTION (uqshl, scalar_u32_shift_imm, none, none) DEF_MVE_FUNCTION (uqshll, scalar_u64_shift_imm, none, none) +DEF_MVE_FUNCTION (urshr, scalar_u32_shift_imm, none, none) DEF_MVE_FUNCTION (urshrl, scalar_u64_shift_imm, none, none) DEF_MVE_FUNCTION (vabavq, binary_acca_int32, all_integer, p_or_none) DEF_MVE_FUNCTION (vabdq, binary, all_integer, mx_or_none) diff --git a/gcc/config/arm/arm-mve-builtins-base.h b/gcc/config/arm/arm-mve-builtins-base.h index 37302621d0b..60bf51bb752 100644 --- a/gcc/config/arm/arm-mve-builtins-base.h +++ b/gcc/config/arm/arm-mve-builtins-base.h @@ -25,13 +25,19 @@ namespace functions { extern const function_base *const asrl; extern const function_base *const lsll; +extern const function_base *const sqrshr; extern const function_base *const sqrshrl; extern const function_base *const sqrshrl_sat48; +extern const function_base *const sqshl; extern const function_base *const sqshll; +extern const function_base *const srshr; extern const function_base *const srshrl; +extern const function_base *const uqrshl; extern const function_base *const uqrshll; extern const function_base *const uqrshll_sat48; +extern const function_base *const uqshl; extern const function_base *const uqshll; +extern const function_base *const urshr; extern const function_base *const urshrl; extern const function_base *const vabavq; extern const function_base *const vabdq; diff --git a/gcc/config/arm/arm-mve-builtins-shapes.cc b/gcc/config/arm/arm-mve-builtins-shapes.cc index f75c7095d94..741c582cef4 100644 --- a/gcc/config/arm/arm-mve-builtins-shapes.cc +++ b/gcc/config/arm/arm-mve-builtins-shapes.cc @@ -1723,6 +1723,82 @@ struct mvn_def : public overloaded_base<0> }; SHAPE (mvn) +/* int32_t foo(int32_t, int32_t) + + Example: sqrshr. + int32_t [__arm_]sqrshr(int32_t value, int32_t shift) */ +struct scalar_s32_shift_def : public nonoverloaded_base +{ + void + build (function_builder &b, const function_group_info &group, + bool preserve_user_namespace) const override + { + build_all (b, "ss32,ss32,ss32", group, MODE_none, preserve_user_namespace); + } +}; +SHAPE (scalar_s32_shift) + +/* int32_t foo(int32_t, const int) + + Check that 'shift' is in the [1,32] range. + + Example: sqshl. + int32_t [__arm_]sqshl(int32_t value, const int shift) */ +struct scalar_s32_shift_imm_def : public nonoverloaded_base +{ + void + build (function_builder &b, const function_group_info &group, + bool preserve_user_namespace) const override + { + build_all (b, "ss32,ss32,su64", group, MODE_none, preserve_user_namespace); + } + + bool + check (function_checker &c) const override + { + return c.require_immediate_range (1, 1, 32); + } +}; +SHAPE (scalar_s32_shift_imm) + +/* uint32_t foo(uint32_t, int32_t) + + Example: uqrshl. + uint32_t [__arm_]uqrshl(uint32_t value, int32_t shift) */ +struct scalar_u32_shift_def : public nonoverloaded_base +{ + void + build (function_builder &b, const function_group_info &group, + bool preserve_user_namespace) const override + { + build_all (b, "su32,su32,ss32", group, MODE_none, preserve_user_namespace); + } +}; +SHAPE (scalar_u32_shift) + +/* uint32_t foo(uint32_t, const int) + + Check that 'shift' is in the [1,32] range. + + Example: uqshl. + uint32_t [__arm_]uqshl(uint32_t value, const int shift) */ +struct scalar_u32_shift_imm_def : public nonoverloaded_base +{ + void + build (function_builder &b, const function_group_info &group, + bool preserve_user_namespace) const override + { + build_all (b, "su32,su32,su64", group, MODE_none, preserve_user_namespace); + } + + bool + check (function_checker &c) const override + { + return c.require_immediate_range (1, 1, 32); + } +}; +SHAPE (scalar_u32_shift_imm) + /* int64_t foo(int64_t, int32_t) Example: asrl diff --git a/gcc/config/arm/arm-mve-builtins-shapes.h b/gcc/config/arm/arm-mve-builtins-shapes.h index 1ab11615ba4..22d06ce0ebd 100644 --- a/gcc/config/arm/arm-mve-builtins-shapes.h +++ b/gcc/config/arm/arm-mve-builtins-shapes.h @@ -67,6 +67,10 @@ namespace arm_mve extern const function_shape *const load_ext_gather_offset; extern const function_shape *const load_gather_base; extern const function_shape *const mvn; + extern const function_shape *const scalar_s32_shift; + extern const function_shape *const scalar_s32_shift_imm; + extern const function_shape *const scalar_u32_shift; + extern const function_shape *const scalar_u32_shift_imm; extern const function_shape *const scalar_s64_shift; extern const function_shape *const scalar_s64_shift_imm; extern const function_shape *const scalar_u64_shift; diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h index 3acb36a2a55..9710be53911 100644 --- a/gcc/config/arm/arm_mve.h +++ b/gcc/config/arm/arm_mve.h @@ -58,56 +58,8 @@ #define vuninitializedq_s64(void) __arm_vuninitializedq_s64(void) #define vuninitializedq_f16(void) __arm_vuninitializedq_f16(void) #define vuninitializedq_f32(void) __arm_vuninitializedq_f32(void) -#define sqrshr(__p0, __p1) __arm_sqrshr(__p0, __p1) -#define sqshl(__p0, __p1) __arm_sqshl(__p0, __p1) -#define srshr(__p0, __p1) __arm_srshr(__p0, __p1) -#define uqrshl(__p0, __p1) __arm_uqrshl(__p0, __p1) -#define uqshl(__p0, __p1) __arm_uqshl(__p0, __p1) -#define urshr(__p0, __p1) __arm_urshr(__p0, __p1) #endif -__extension__ extern __inline uint32_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_uqrshl (uint32_t value, int32_t shift) -{ - return __builtin_mve_uqrshl_si (value, shift); -} - -__extension__ extern __inline int32_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_sqrshr (int32_t value, int32_t shift) -{ - return __builtin_mve_sqrshr_si (value, shift); -} - -__extension__ extern __inline uint32_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_uqshl (uint32_t value, const int shift) -{ - return __builtin_mve_uqshl_si (value, shift); -} - -__extension__ extern __inline uint32_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_urshr (uint32_t value, const int shift) -{ - return __builtin_mve_urshr_si (value, shift); -} - -__extension__ extern __inline int32_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_sqshl (int32_t value, const int shift) -{ - return __builtin_mve_sqshl_si (value, shift); -} - -__extension__ extern __inline int32_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_srshr (int32_t value, const int shift) -{ - return __builtin_mve_srshr_si (value, shift); -} - #ifdef __cplusplus __extension__ extern __inline uint8x16_t diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index e9de7f09dbb..1ea1f5f1b4b 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -4363,7 +4363,7 @@ (define_insn "mve_urshr_si" ;; (define_insn "mve_sqshl_si" [(set (match_operand:SI 0 "arm_general_register_operand" "=r") - (ss_ashift:SI (match_operand:DI 1 "arm_general_register_operand" "0") + (ss_ashift:SI (match_operand:SI 1 "arm_general_register_operand" "0") (match_operand:SI 2 "immediate_operand" "Pg")))] "TARGET_HAVE_MVE" "sqshl%?\\t%1, %2" @@ -4374,7 +4374,7 @@ (define_insn "mve_sqshl_si" ;; (define_insn "mve_srshr_si" [(set (match_operand:SI 0 "arm_general_register_operand" "=r") - (unspec:SI [(match_operand:DI 1 "arm_general_register_operand" "0") + (unspec:SI [(match_operand:SI 1 "arm_general_register_operand" "0") (match_operand:SI 2 "immediate_operand" "Pg")] SRSHR))] "TARGET_HAVE_MVE" diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl_check_shift.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl_check_shift.c new file mode 100644 index 00000000000..05191669285 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshl_check_shift.c @@ -0,0 +1,24 @@ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ + +#include "arm_mve.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t +foo (int32_t value) +{ + return sqshl (value, 33); /* { dg-error {passing 33 to argument 2 of 'sqshl', which expects a value in the range \[1, 32\]} } */ +} + +int32_t +foo1 (int32_t value) +{ + return sqshl (value, -1); /* { dg-error {passing -1 to argument 2 of 'sqshl', which expects a value in the range \[1, 32\]} } */ +} + +#ifdef __cplusplus +} +#endif diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr_check_shift.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr_check_shift.c new file mode 100644 index 00000000000..98c5e17a426 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshr_check_shift.c @@ -0,0 +1,24 @@ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ + +#include "arm_mve.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t +foo (int32_t value) +{ + return srshr (value, 33); /* { dg-error {passing 33 to argument 2 of 'srshr', which expects a value in the range \[1, 32\]} } */ +} + +int32_t +foo1 (int32_t value) +{ + return srshr (value, -1); /* { dg-error {passing -1 to argument 2 of 'srshr', which expects a value in the range \[1, 32\]} } */ +} + +#ifdef __cplusplus +} +#endif diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl_check_shift.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl_check_shift.c new file mode 100644 index 00000000000..eef1bc03254 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshl_check_shift.c @@ -0,0 +1,24 @@ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ + +#include "arm_mve.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t +foo (uint32_t value) +{ + return uqshl (value, 33); /* { dg-error {passing 33 to argument 2 of 'uqshl', which expects a value in the range \[1, 32\]} } */ +} + +uint32_t +foo1 (uint32_t value) +{ + return uqshl (value, -1); /* { dg-error {passing -1 to argument 2 of 'uqshl', which expects a value in the range \[1, 32\]} } */ +} + +#ifdef __cplusplus +} +#endif diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr_check_shift.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr_check_shift.c new file mode 100644 index 00000000000..744bf7ca795 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshr_check_shift.c @@ -0,0 +1,24 @@ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ + +#include "arm_mve.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t +foo (uint32_t value) +{ + return urshr (value, 33); /* { dg-error {passing 33 to argument 2 of 'urshr', which expects a value in the range \[1, 32\]} } */ +} + +uint32_t +foo1 (uint32_t value) +{ + return urshr (value, -1); /* { dg-error {passing -1 to argument 2 of 'urshr', which expects a value in the range \[1, 32\]} } */ +} + +#ifdef __cplusplus +} +#endif -- 2.34.1