]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
arm: [MVE intrinsics] rework sqshll srshrl uqshll urshrl
authorChristophe Lyon <christophe.lyon@linaro.org>
Fri, 19 Sep 2025 13:14:51 +0000 (13:14 +0000)
committerChristophe Lyon <christophe.lyon@linaro.org>
Fri, 14 Nov 2025 20:55:29 +0000 (20:55 +0000)
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.

gcc/config/arm/arm-mve-builtins-base.cc
gcc/config/arm/arm-mve-builtins-base.def
gcc/config/arm/arm-mve-builtins-base.h
gcc/config/arm/arm-mve-builtins-shapes.cc
gcc/config/arm/arm-mve-builtins-shapes.h
gcc/config/arm/arm_mve.h
gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll_check_shift.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl_check_shift.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll_check_shift.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl_check_shift.c [new file with mode: 0644]

index d2989044dd3872a909f5479c9670011d6ccd60e2..a1c667faa730f91c17063bee1c55ed29947ff9c9 100644 (file)
@@ -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))
index fdeb7411e757d5d1fe2993e1de1e891456daf97e..9602ff9fa93049c608d03d9c95d00d27e6bfaab3 100644 (file)
@@ -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)
index dfec21936724fee9480dfa824a3a9ef6a4dab7a0..c7c0c7f9779aa2b877b7fe7391be80155826a9d3 100644 (file)
@@ -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;
index 02458c75755d406357f1683e8c36b786e064364f..35ae2724e0a4c0cafe3edd59eea4116802178669 100644 (file)
@@ -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
index 89ef75c54436d0af7494664a0bab1393ab4782ba..4e6a23fcca6b6771f87450a7b6a0e5a9a1586af1 100644 (file)
@@ -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;
index 5a12d982c50acff142b766d411ff809d37fdb5e8..877bbf35014d725da350dd5590b928b96545ad26 100644 (file)
 #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 (file)
index 0000000..6b5fc41
--- /dev/null
@@ -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 (file)
index 0000000..d29a239
--- /dev/null
@@ -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 (file)
index 0000000..485fd01
--- /dev/null
@@ -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 (file)
index 0000000..9d0d3b1
--- /dev/null
@@ -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