https://gcc.gnu.org/g:54b3c41e27f238c16c7f907ead83ed10cac774da
commit r16-5289-g54b3c41e27f238c16c7f907ead83ed10cac774da Author: Christophe Lyon <[email protected]> Date: Sun Aug 24 21:04:35 2025 +0000 arm: [MVE intrinsics] rework sqrshr sqshl srshr uqrshl uqshl urshr 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 support 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 operand 1 mode. 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. Diff: --- 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 | 47 ------------- 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(+), 49 deletions(-) diff --git a/gcc/config/arm/arm-mve-builtins-base.cc b/gcc/config/arm/arm-mve-builtins-base.cc index a1c667faa730..1b2b18706359 100644 --- a/gcc/config/arm/arm-mve-builtins-base.cc +++ b/gcc/config/arm/arm-mve-builtins-base.cc @@ -1172,13 +1172,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 }; @@ -1209,6 +1215,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; @@ -1217,6 +1227,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; @@ -1233,10 +1255,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; @@ -1437,13 +1467,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 9602ff9fa930..f2442617aa47 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 c7c0c7f9779a..aac5f8067eb0 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 35ae2724e0a4..1eeae176584e 100644 --- a/gcc/config/arm/arm-mve-builtins-shapes.cc +++ b/gcc/config/arm/arm-mve-builtins-shapes.cc @@ -1682,6 +1682,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 4e6a23fcca6b..c384da8c6a72 100644 --- a/gcc/config/arm/arm-mve-builtins-shapes.h +++ b/gcc/config/arm/arm-mve-builtins-shapes.h @@ -66,6 +66,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 877bbf35014d..405a3d019650 100644 --- a/gcc/config/arm/arm_mve.h +++ b/gcc/config/arm/arm_mve.h @@ -80,12 +80,6 @@ #define vgetq_lane_u16(__a, __idx) __arm_vgetq_lane_u16(__a, __idx) #define vgetq_lane_u32(__a, __idx) __arm_vgetq_lane_u32(__a, __idx) #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 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 /* For big-endian, GCC's vector indices are reversed within each 64 bits @@ -236,47 +230,6 @@ __arm_vgetq_lane_u64 (uint64x2_t __a, const int __idx) return __a[__ARM_LANEQ(__a,__idx)]; } -__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); -} #if (__ARM_FEATURE_MVE & 2) /* MVE Floating point. */ diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index b416d0c873c9..33b57080b268 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -4374,7 +4374,7 @@ ;; (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" @@ -4385,7 +4385,7 @@ ;; (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 000000000000..051916692854 --- /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 000000000000..98c5e17a4266 --- /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 000000000000..eef1bc03254b --- /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 000000000000..744bf7ca7958 --- /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
