From: Christophe Lyon <[email protected]>
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.
---
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 bcb97108b59..c36c64a16d6 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
};
@@ -1283,6 +1289,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;
@@ -1291,6 +1301,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;
@@ -1307,10 +1329,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;
@@ -1492,13 +1522,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 888837674ed..2f2c2d4a868 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -4375,7 +4375,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"
@@ -4386,7 +4386,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 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