[Arm] : MVE: Fix vec extracts to memory

Message ID 76d8dbd0-5507-cde1-9474-742bbcd6af43@arm.com
State New
Headers show
Series
  • [Arm] : MVE: Fix vec extracts to memory
Related show

Commit Message

Andre Vieira (lists) April 7, 2020, 2:13 p.m.
Hi,

This patch fixes vec extracts to memory that can arise from code as seen 
in the testcase added. The patch fixes this by allowing mem operands in 
the set of mve_vec_extract patterns, which given the only '=r' 
constraint will lead to the scalar value being written to a register and 
then stored in memory using scalar store pattern.

Regression tested on arm-none-eabi.

Is this OK for trunk?

gcc/ChangeLog:
2020-04-07  Andre Vieira  <andre.simoesdiasvieira@arm.com>

         * config/arm/mve.md (mve_vec_extract*): Allow memory operands 
in set.

gcc/testsuite/ChangeLog:
2020-04-07  Andre Vieira  <andre.simoesdiasvieira@arm.com>

         * gcc.target/arm/mve/intrinsics/mve_vec_extracts_from_memory.c: 
New test.

Comments

Kyrylo Tkachov April 7, 2020, 2:49 p.m. | #1
> -----Original Message-----

> From: Andre Vieira (lists) <andre.simoesdiasvieira@arm.com>

> Sent: 07 April 2020 15:14

> To: gcc-patches@gcc.gnu.org

> Cc: Kyrylo Tkachov <Kyrylo.Tkachov@arm.com>

> Subject: [PATCH][GCC][Arm]: MVE: Fix vec extracts to memory

> 

> Hi,

> 

> This patch fixes vec extracts to memory that can arise from code as seen

> in the testcase added. The patch fixes this by allowing mem operands in

> the set of mve_vec_extract patterns, which given the only '=r'

> constraint will lead to the scalar value being written to a register and

> then stored in memory using scalar store pattern.

> 

> Regression tested on arm-none-eabi.

> 

> Is this OK for trunk?


Ok.
Thanks,
Kyrill

> 

> gcc/ChangeLog:

> 2020-04-07  Andre Vieira  <andre.simoesdiasvieira@arm.com>

> 

>          * config/arm/mve.md (mve_vec_extract*): Allow memory operands

> in set.

> 

> gcc/testsuite/ChangeLog:

> 2020-04-07  Andre Vieira  <andre.simoesdiasvieira@arm.com>

> 

>          * gcc.target/arm/mve/intrinsics/mve_vec_extracts_from_memory.c:

> New test.

Patch

diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 3c75f9ebc70d5765a59934b944955c757b6b2195..c49c14c4240838ce086f424f58726e2e94cf190e 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -10993,7 +10993,7 @@  (define_insn "mve_vld4q<mode>"
 ;; [vgetq_lane_u, vgetq_lane_s, vgetq_lane_f])
 ;;
 (define_insn "mve_vec_extract<mode><V_elem_l>"
- [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
+ [(set (match_operand:<V_elem> 0 "nonimmediate_operand" "=r")
    (vec_select:<V_elem>
     (match_operand:MVE_VLD_ST 1 "s_register_operand" "w")
     (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
@@ -11011,7 +11011,7 @@  (define_insn "mve_vec_extract<mode><V_elem_l>"
  [(set_attr "type" "mve_move")])
 
 (define_insn "mve_vec_extractv2didi"
- [(set (match_operand:DI 0 "s_register_operand" "=r")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r")
    (vec_select:DI
     (match_operand:V2DI 1 "s_register_operand" "w")
     (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
@@ -11024,7 +11024,7 @@  (define_insn "mve_vec_extractv2didi"
   if (elt == 0)
    return "vmov\t%Q0, %R0, %e1";
   else
-   return "vmov\t%J0, %K0, %f1";
+   return "vmov\t%Q0, %R0, %f1";
 }
  [(set_attr "type" "mve_move")])
 
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vec_extracts_from_memory.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vec_extracts_from_memory.c
new file mode 100644
index 0000000000000000000000000000000000000000..12f2f2d38d3c2e189a9c06f21fc63e2c23e2e721
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_vec_extracts_from_memory.c
@@ -0,0 +1,40 @@ 
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-additional-options "-O3" } */
+
+#include "arm_mve.h"
+
+uint8x16_t *vu8;
+int8x16_t *vs8;
+uint16x8_t *vu16;
+int16x8_t *vs16;
+uint32x4_t *vu32;
+int32x4_t *vs32;
+uint64x2_t *vu64;
+int64x2_t *vs64;
+float16x8_t *vf16;
+float32x4_t *vf32;
+uint8_t u8;
+uint16_t u16;
+uint32_t u32;
+uint64_t u64;
+int8_t s8;
+int16_t s16;
+int32_t s32;
+int64_t s64;
+float16_t f16;
+float32_t f32;
+
+void foo (void)
+{
+  u8 = vgetq_lane (*vu8, 1);
+  u16 = vgetq_lane (*vu16, 1);
+  u32 = vgetq_lane (*vu32, 1);
+  u64 = vgetq_lane (*vu64, 1);
+  s8 = vgetq_lane (*vs8, 1);
+  s16 = vgetq_lane (*vs16, 1);
+  s32 = vgetq_lane (*vs32, 1);
+  s64 = vgetq_lane (*vs64, 1);
+  f16 = vgetq_lane (*vf16, 1);
+  f32 = vgetq_lane (*vf32, 1);
+}