https://gcc.gnu.org/g:8dea981b8f6df2b110c382c2cd17bdba36487a2d
commit r16-5288-g8dea981b8f6df2b110c382c2cd17bdba36487a2d Author: Christophe Lyon <[email protected]> Date: Fri Sep 19 13:14:51 2025 +0000 arm: [MVE intrinsics] rework sqshll srshrl uqshll urshrl Implement sqshll, srshrl, uqshll and urshrl using the new MVE builtins framework. gcc/ChangeLog: * config/arm/arm-mve-builtins-base.cc (enum which_scalar_shift): Add ss_SQSHLL, ss_SRSHRL, ss_UQSHLL, ss_URSHRL. (mve_function_scalar_shift): Add support for ss_SQSHLL, ss_SRSHRL, ss_UQSHLL, ss_URSHRL. * config/arm/arm-mve-builtins-base.def (sqshll, srshrl, uqshll) (urshrl): New. * config/arm/arm-mve-builtins-base.h (sqshll, srshrl, uqshll) (urshrl): New. * config/arm/arm-mve-builtins-shapes.cc (scalar_s64_shift_imm) (scalar_u64_shift_imm): New. * config/arm/arm-mve-builtins-shapes.h (scalar_s64_shift_imm) (scalar_u64_shift_imm): New. * config/arm/arm_mve.h (sqshll): Delete. (srshrl): Delete. (uqshll): Delete. (urshrl): Delete. (__arm_uqshll): Delete. (__arm_urshrl): Delete. (__arm_srshrl): Delete. (__arm_sqshll): Delete. gcc/testsuite/ChangeLog: * gcc.target/arm/mve/intrinsics/sqshll_check_shift.c: New test. * gcc.target/arm/mve/intrinsics/srshrl_check_shift.c: New test. * gcc.target/arm/mve/intrinsics/uqshll_check_shift.c: New test. * gcc.target/arm/mve/intrinsics/urshrl_check_shift.c: New test. Diff: --- gcc/config/arm/arm-mve-builtins-base.cc | 24 +++++++++++ gcc/config/arm/arm-mve-builtins-base.def | 4 ++ gcc/config/arm/arm-mve-builtins-base.h | 4 ++ gcc/config/arm/arm-mve-builtins-shapes.cc | 46 ++++++++++++++++++++++ gcc/config/arm/arm-mve-builtins-shapes.h | 2 + gcc/config/arm/arm_mve.h | 32 --------------- .../arm/mve/intrinsics/sqshll_check_shift.c | 24 +++++++++++ .../arm/mve/intrinsics/srshrl_check_shift.c | 24 +++++++++++ .../arm/mve/intrinsics/uqshll_check_shift.c | 24 +++++++++++ .../arm/mve/intrinsics/urshrl_check_shift.c | 24 +++++++++++ 10 files changed, 176 insertions(+), 32 deletions(-) diff --git a/gcc/config/arm/arm-mve-builtins-base.cc b/gcc/config/arm/arm-mve-builtins-base.cc index d2989044dd38..a1c667faa730 100644 --- a/gcc/config/arm/arm-mve-builtins-base.cc +++ b/gcc/config/arm/arm-mve-builtins-base.cc @@ -1174,8 +1174,12 @@ enum which_scalar_shift { ss_LSLL, ss_SQRSHRL, ss_SQRSHRL_SAT48, + ss_SQSHLL, + ss_SRSHRL, ss_UQRSHLL, ss_UQRSHLL_SAT48, + ss_UQSHLL, + ss_URSHRL }; class mve_function_scalar_shift : public function_base @@ -1213,6 +1217,14 @@ public: code = code_for_mve_sqrshrl_sat_di (SQRSHRL_48); break; + case ss_SQSHLL: + code = CODE_FOR_mve_sqshll_di; + break; + + case ss_SRSHRL: + code = CODE_FOR_mve_srshrl_di; + break; + case ss_UQRSHLL: code = code_for_mve_uqrshll_sat_di (UQRSHLL_64); break; @@ -1221,6 +1233,14 @@ public: code = code_for_mve_uqrshll_sat_di (UQRSHLL_48); break; + case ss_UQSHLL: + code = CODE_FOR_mve_uqshll_di; + break; + + case ss_URSHRL: + code = CODE_FOR_mve_urshrl_di; + break; + default: gcc_unreachable (); } @@ -1419,8 +1439,12 @@ FUNCTION (asrl, mve_function_scalar_shift, (ss_ASRL)) FUNCTION (lsll, mve_function_scalar_shift, (ss_LSLL)) FUNCTION (sqrshrl, mve_function_scalar_shift, (ss_SQRSHRL)) FUNCTION (sqrshrl_sat48, mve_function_scalar_shift, (ss_SQRSHRL_SAT48)) +FUNCTION (sqshll, mve_function_scalar_shift, (ss_SQSHLL)) +FUNCTION (srshrl, mve_function_scalar_shift, (ss_SRSHRL)) FUNCTION (uqrshll, mve_function_scalar_shift, (ss_UQRSHLL)) FUNCTION (uqrshll_sat48, mve_function_scalar_shift, (ss_UQRSHLL_SAT48)) +FUNCTION (uqshll, mve_function_scalar_shift, (ss_UQSHLL)) +FUNCTION (urshrl, mve_function_scalar_shift, (ss_URSHRL)) FUNCTION_PRED_P_S_U (vabavq, VABAVQ) FUNCTION_WITHOUT_N (vabdq, VABDQ) FUNCTION (vabsq, unspec_based_mve_function_exact_insn, (ABS, ABS, ABS, -1, -1, -1, VABSQ_M_S, -1, VABSQ_M_F, -1, -1, -1)) diff --git a/gcc/config/arm/arm-mve-builtins-base.def b/gcc/config/arm/arm-mve-builtins-base.def index fdeb7411e757..9602ff9fa930 100644 --- a/gcc/config/arm/arm-mve-builtins-base.def +++ b/gcc/config/arm/arm-mve-builtins-base.def @@ -22,8 +22,12 @@ DEF_MVE_FUNCTION (asrl, scalar_s64_shift, none, none) DEF_MVE_FUNCTION (lsll, scalar_u64_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 (sqshll, scalar_s64_shift_imm, none, none) +DEF_MVE_FUNCTION (srshrl, scalar_s64_shift_imm, none, none) DEF_MVE_FUNCTION (uqrshll, scalar_u64_shift, none, none) DEF_MVE_FUNCTION (uqrshll_sat48, scalar_u64_shift, none, none) +DEF_MVE_FUNCTION (uqshll, scalar_u64_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) DEF_MVE_FUNCTION (vabsq, unary, all_signed, mx_or_none) diff --git a/gcc/config/arm/arm-mve-builtins-base.h b/gcc/config/arm/arm-mve-builtins-base.h index dfec21936724..c7c0c7f9779a 100644 --- a/gcc/config/arm/arm-mve-builtins-base.h +++ b/gcc/config/arm/arm-mve-builtins-base.h @@ -27,8 +27,12 @@ extern const function_base *const asrl; extern const function_base *const lsll; extern const function_base *const sqrshrl; extern const function_base *const sqrshrl_sat48; +extern const function_base *const sqshll; +extern const function_base *const srshrl; extern const function_base *const uqrshll; extern const function_base *const uqrshll_sat48; +extern const function_base *const uqshll; +extern const function_base *const urshrl; extern const function_base *const vabavq; extern const function_base *const vabdq; extern const function_base *const vabsq; diff --git a/gcc/config/arm/arm-mve-builtins-shapes.cc b/gcc/config/arm/arm-mve-builtins-shapes.cc index 02458c75755d..35ae2724e0a4 100644 --- a/gcc/config/arm/arm-mve-builtins-shapes.cc +++ b/gcc/config/arm/arm-mve-builtins-shapes.cc @@ -1697,6 +1697,29 @@ struct scalar_s64_shift_def : public nonoverloaded_base }; SHAPE (scalar_s64_shift) +/* int64_t foo(int64_t, const int) + + Check that 'shift' is in the [1,32] range. + + Example: sqshll. + int64_t [__arm_]sqshll(int64_t value, const int shift) */ +struct scalar_s64_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, "ss64,ss64,su64", group, MODE_none, preserve_user_namespace); + } + + bool + check (function_checker &c) const override + { + return c.require_immediate_range (1, 1, 32); + } +}; +SHAPE (scalar_s64_shift_imm) + /* uint64_t foo(uint64_t, int32_t) Example: lsll. @@ -1712,6 +1735,29 @@ struct scalar_u64_shift_def : public nonoverloaded_base }; SHAPE (scalar_u64_shift) +/* uint64_t foo(uint64_t, const int) + + Check that 'shift' is in the [1,32] range. + + Example: uqshll. + uint64_t [__arm_]uqshll(uint64_t value, const int shift) */ +struct scalar_u64_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, "su64,su64,su64", group, MODE_none, preserve_user_namespace); + } + + bool + check (function_checker &c) const override + { + return c.require_immediate_range (1, 1, 32); + } +}; +SHAPE (scalar_u64_shift_imm) + /* void vfoo[_t0](<X>_t *, <T0>[xN]_t) where <X> might be tied to <t0> (for non-truncating stores) or might diff --git a/gcc/config/arm/arm-mve-builtins-shapes.h b/gcc/config/arm/arm-mve-builtins-shapes.h index 89ef75c54436..4e6a23fcca6b 100644 --- a/gcc/config/arm/arm-mve-builtins-shapes.h +++ b/gcc/config/arm/arm-mve-builtins-shapes.h @@ -67,7 +67,9 @@ namespace arm_mve extern const function_shape *const load_gather_base; extern const function_shape *const mvn; 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; + extern const function_shape *const scalar_u64_shift_imm; extern const function_shape *const store; extern const function_shape *const store_scatter_base; extern const function_shape *const store_scatter_offset; diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h index 5a12d982c50a..877bbf35014d 100644 --- a/gcc/config/arm/arm_mve.h +++ b/gcc/config/arm/arm_mve.h @@ -82,14 +82,10 @@ #define vgetq_lane_u64(__a, __idx) __arm_vgetq_lane_u64(__a, __idx) #define sqrshr(__p0, __p1) __arm_sqrshr(__p0, __p1) #define sqshl(__p0, __p1) __arm_sqshl(__p0, __p1) -#define sqshll(__p0, __p1) __arm_sqshll(__p0, __p1) #define srshr(__p0, __p1) __arm_srshr(__p0, __p1) -#define srshrl(__p0, __p1) __arm_srshrl(__p0, __p1) #define uqrshl(__p0, __p1) __arm_uqrshl(__p0, __p1) #define uqshl(__p0, __p1) __arm_uqshl(__p0, __p1) -#define uqshll(__p0, __p1) __arm_uqshll(__p0, __p1) #define urshr(__p0, __p1) __arm_urshr(__p0, __p1) -#define urshrl(__p0, __p1) __arm_urshrl(__p0, __p1) #endif /* For big-endian, GCC's vector indices are reversed within each 64 bits @@ -240,34 +236,6 @@ __arm_vgetq_lane_u64 (uint64x2_t __a, const int __idx) return __a[__ARM_LANEQ(__a,__idx)]; } -__extension__ extern __inline uint64_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_uqshll (uint64_t value, const int shift) -{ - return __builtin_mve_uqshll_di (value, shift); -} - -__extension__ extern __inline uint64_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_urshrl (uint64_t value, const int shift) -{ - return __builtin_mve_urshrl_di (value, shift); -} - -__extension__ extern __inline int64_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_srshrl (int64_t value, const int shift) -{ - return __builtin_mve_srshrl_di (value, shift); -} - -__extension__ extern __inline int64_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_sqshll (int64_t value, const int shift) -{ - return __builtin_mve_sqshll_di (value, shift); -} - __extension__ extern __inline uint32_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __arm_uqrshl (uint32_t value, int32_t shift) diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll_check_shift.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll_check_shift.c new file mode 100644 index 000000000000..6b5fc41b0035 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll_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 + +int64_t +foo (int64_t value) +{ + return sqshll (value, 33); /* { dg-error {passing 33 to argument 2 of 'sqshll', which expects a value in the range \[1, 32\]} } */ +} + +int64_t +foo1 (int64_t value) +{ + return sqshll (value, -1); /* { dg-error {passing -1 to argument 2 of 'sqshll', which expects a value in the range \[1, 32\]} } */ +} + +#ifdef __cplusplus +} +#endif diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl_check_shift.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl_check_shift.c new file mode 100644 index 000000000000..d29a2390a197 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl_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 + +int64_t +foo (int64_t value) +{ + return srshrl (value, 33); /* { dg-error {passing 33 to argument 2 of 'srshrl', which expects a value in the range \[1, 32\]} } */ +} + +int64_t +foo1 (int64_t value) +{ + return srshrl (value, -1); /* { dg-error {passing -1 to argument 2 of 'srshrl', which expects a value in the range \[1, 32\]} } */ +} + +#ifdef __cplusplus +} +#endif diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll_check_shift.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll_check_shift.c new file mode 100644 index 000000000000..485fd01d4e77 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll_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 + +uint64_t +foo (uint64_t value) +{ + return uqshll (value, 33); /* { dg-error {passing 33 to argument 2 of 'uqshll', which expects a value in the range \[1, 32\]} } */ +} + +uint64_t +foo1 (uint64_t value) +{ + return uqshll (value, -1); /* { dg-error {passing -1 to argument 2 of 'uqshll', which expects a value in the range \[1, 32\]} } */ +} + +#ifdef __cplusplus +} +#endif diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl_check_shift.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl_check_shift.c new file mode 100644 index 000000000000..9d0d3b1d5ee9 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl_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 + +uint64_t +foo (uint64_t value) +{ + return urshrl (value, 33); /* { dg-error {passing 33 to argument 2 of 'urshrl', which expects a value in the range \[1, 32\]} } */ +} + +uint64_t +foo1 (uint64_t value) +{ + return urshrl (value, -1); /* { dg-error {passing -1 to argument 2 of 'urshrl', which expects a value in the range \[1, 32\]} } */ +} + +#ifdef __cplusplus +} +#endif
