From: Christophe Lyon <[email protected]>
A constant value with the top bit of a 16-bit const passed to vbicq_n_u16 will
generate invalid assembly. Avoid this by masking the constant during assembly
generation.
The same applies to vorrq_n and vmvnq_n.
gcc/ChangeLog:
PR target/122175
* config/arm/iterators.md (asm_const_size): New mode attr.
* config/arm/mve.md (@mve_<mve_insn>q_n_<supf><mode>): Use it.
gcc/testsuite/ChangeLog:
PR target/122175
* gcc.target/arm/mve/intrinsics/pr122175.c: New test.
Co-authored-by: Richard Earnshaw <[email protected]>
---
gcc/config/arm/iterators.md | 8 ++++
gcc/config/arm/mve.md | 8 ++--
.../gcc.target/arm/mve/intrinsics/pr122175.c | 38 +++++++++++++++++++
3 files changed, 50 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/pr122175.c
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index dfbe0270c8d..592613d9890 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -2061,6 +2061,14 @@
(V2QI "v2qi")])
(define_mode_attr MVE_vctp [(V16BI "8") (V8BI "16") (V4BI "32") (V2QI "64")])
+;; Assembly modifier for a const_int operand to narrow it to a
+;; specific mode. For vector modes this is the element size.
+;; Currently only supports SI and HI.
+
+(define_mode_attr asm_const_size [(SI "") (HI "L")
+ (V4SI "") (V2SI "")
+ (V8HI "L") (V4HI "L")])
+
;;----------------------------------------------------------------------------
;; Code attributes
;;----------------------------------------------------------------------------
diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 87b45b2e41c..bd52a916ff8 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -417,7 +417,7 @@
VMVNQ_N))
]
"TARGET_HAVE_MVE"
- "<mve_insn>.i%#<V_sz_elem>\t%q0, %1"
+ "<mve_insn>.i%#<V_sz_elem>\t%q0, %<asm_const_size>1"
[(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_<mve_insn>q_n_<supf><mode>"))
(set_attr "type" "mve_move")
])
@@ -1444,7 +1444,7 @@
MVE_INT_N_BINARY_LOGIC))
]
"TARGET_HAVE_MVE"
- "<mve_insn>.i%#<V_sz_elem> %q0, %2"
+ "<mve_insn>.i%#<V_sz_elem> %q0, %<asm_const_size>2"
[(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_<mve_insn>q_n_<supf><mode>"))
(set_attr "type" "mve_move")
])
@@ -2335,7 +2335,7 @@
VMVNQ_M_N))
]
"TARGET_HAVE_MVE"
- "vpst\;<mve_insn>t.i%#<V_sz_elem>\t%q0, %2"
+ "vpst\;<mve_insn>t.i%#<V_sz_elem>\t%q0, %<asm_const_size>2"
[(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_<mve_insn>q_n_<supf><mode>"))
(set_attr "type" "mve_move")
(set_attr "length""8")])
@@ -2353,7 +2353,7 @@
MVE_INT_M_N_BINARY_LOGIC))
]
"TARGET_HAVE_MVE"
- "vpst\;<mve_insn>t.i%#<V_sz_elem>\t%q0, %2"
+ "vpst\;<mve_insn>t.i%#<V_sz_elem>\t%q0, %<asm_const_size>2"
[(set (attr "mve_unpredicated_insn") (symbol_ref "CODE_FOR_mve_<mve_insn>q_n_<supf><mode>"))
(set_attr "type" "mve_move")
(set_attr "length""8")])
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr122175.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr122175.c
new file mode 100644
index 00000000000..42873d011a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr122175.c
@@ -0,0 +1,38 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-additional-options "-O2" } */
+
+#include <arm_mve.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint16x8_t test_1(uint16x8_t v11) {
+ return vbicq_n_u16(v11, 0x8000);
+}
+
+uint16x8_t test_2(uint16x8_t v11) {
+ return vorrq_n_u16(v11, 0x8000);
+}
+
+uint16x8_t test_3() {
+ return vmvnq_n_u16(0x8000);
+}
+
+mve_pred16_t pred;
+uint16x8_t test_4(uint16x8_t v11) {
+ return vbicq_m_n_u16(v11, 0x8000, pred);
+}
+
+uint16x8_t test_5(uint16x8_t v11) {
+ return vorrq_m_n_u16(v11, 0x8000, pred);
+}
+
+uint16x8_t test_6() {
+ return vmvnq_x_n_u16(0x8000, pred);
+}
+
+#ifdef __cplusplus
+}
+#endif