public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed 1/2] arm: fix some issues in mve_vector_mem_operand
@ 2022-05-13 10:28 Richard Earnshaw
  2022-05-13 10:28 ` [committed 2/2] arm: correctly handle misaligned MEMs on MVE [PR105463] Richard Earnshaw
  0 siblings, 1 reply; 2+ messages in thread
From: Richard Earnshaw @ 2022-05-13 10:28 UTC (permalink / raw)
  To: gcc-patches; +Cc: Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 512 bytes --]


There are a couple of issues with the mve_vector_mem_operand function.
Firstly, SP is permitted as a register provided there is no write-back
operation.  Secondly, there were some cases where 'strict' was not
being applied when checking which registers had been used.

gcc/ChangeLog:

	* config/arm/arm.cc (mve_vector_mem_operand): Allow SP_REGNUM
	when there is no write-back.  Fix use when strict is true.
---
 gcc/config/arm/arm.cc | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-arm-fix-some-issues-in-mve_vector_mem_operand.patch --]
[-- Type: text/x-patch; name="0001-arm-fix-some-issues-in-mve_vector_mem_operand.patch", Size: 1851 bytes --]

diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 69a18c2f157..2afe0445ed5 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -13527,7 +13527,7 @@ mve_vector_mem_operand (machine_mode mode, rtx op, bool strict)
       int reg_no = REGNO (op);
       return (((mode == E_V8QImode || mode == E_V4QImode || mode == E_V4HImode)
 	       ? reg_no <= LAST_LO_REGNUM
-	       :(reg_no < LAST_ARM_REGNUM && reg_no != SP_REGNUM))
+	       : reg_no < LAST_ARM_REGNUM)
 	      || (!strict && reg_no >= FIRST_PSEUDO_REGISTER));
     }
   code = GET_CODE (op);
@@ -13536,10 +13536,10 @@ mve_vector_mem_operand (machine_mode mode, rtx op, bool strict)
       || code == PRE_INC || code == POST_DEC)
     {
       reg_no = REGNO (XEXP (op, 0));
-      return ((mode == E_V8QImode || mode == E_V4QImode || mode == E_V4HImode)
-	      ? reg_no <= LAST_LO_REGNUM
-	      :(reg_no < LAST_ARM_REGNUM && reg_no != SP_REGNUM))
-	|| reg_no >= FIRST_PSEUDO_REGISTER;
+      return (((mode == E_V8QImode || mode == E_V4QImode || mode == E_V4HImode)
+	       ? reg_no <= LAST_LO_REGNUM
+	       :(reg_no < LAST_ARM_REGNUM && reg_no != SP_REGNUM))
+	      || (!strict && reg_no >= FIRST_PSEUDO_REGISTER));
     }
   else if (((code == POST_MODIFY || code == PRE_MODIFY)
 	    && GET_CODE (XEXP (op, 1)) == PLUS
@@ -13580,10 +13580,11 @@ mve_vector_mem_operand (machine_mode mode, rtx op, bool strict)
 	  default:
 	    return FALSE;
 	}
-      return reg_no >= FIRST_PSEUDO_REGISTER
-	|| (MVE_STN_LDW_MODE (mode)
-	    ? reg_no <= LAST_LO_REGNUM
-	    : (reg_no < LAST_ARM_REGNUM && reg_no != SP_REGNUM));
+      return ((!strict && reg_no >= FIRST_PSEUDO_REGISTER)
+	      || (MVE_STN_LDW_MODE (mode)
+		  ? reg_no <= LAST_LO_REGNUM
+		  : (reg_no < LAST_ARM_REGNUM
+		     && (code == PLUS || reg_no != SP_REGNUM))));
     }
   return FALSE;
 }

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [committed 2/2] arm: correctly handle misaligned MEMs on MVE [PR105463]
  2022-05-13 10:28 [committed 1/2] arm: fix some issues in mve_vector_mem_operand Richard Earnshaw
@ 2022-05-13 10:28 ` Richard Earnshaw
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Earnshaw @ 2022-05-13 10:28 UTC (permalink / raw)
  To: gcc-patches; +Cc: Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 1013 bytes --]


Vector operations in MVE must be aligned to the element size, so if we
are asked for a misaligned move in a wider mode we must recast it to a
form suitable for the known alignment (larger elements have better
address offset ranges, so there is some advantage to using wider
element sizes if possible).  Whilst fixing this, also rework the
predicates used for validating operands - the Neon predicates are
not right for MVE.

gcc/ChangeLog:

	PR target/105463
	* config/arm/mve.md (*movmisalign<mode>_mve_store): Use
	mve_memory_operand.
	(*movmisalign<mode>_mve_load): Likewise.
	* config/arm/vec-common.md (movmisalign<mode>): Convert to generator
	form...
	(@movmisalign<mode>): ... thus.  Use generic predicates and then
	rework operands if they are not valid.  For MVE rework to a
	narrower element size if the alignment is not high enough.
---
 gcc/config/arm/mve.md        |  4 +-
 gcc/config/arm/vec-common.md | 90 ++++++++++++++++++++++++++++--------
 2 files changed, 73 insertions(+), 21 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0002-arm-correctly-handle-misaligned-MEMs-on-MVE-PR105463.patch --]
[-- Type: text/x-patch; name="0002-arm-correctly-handle-misaligned-MEMs-on-MVE-PR105463.patch", Size: 4562 bytes --]

diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 369d7a79f6c..f16991c0a34 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -10462,7 +10462,7 @@ (define_insn "arm_vcx3q<a>_p_v16qi"
 )
 
 (define_insn "*movmisalign<mode>_mve_store"
-  [(set (match_operand:MVE_VLD_ST 0 "neon_permissive_struct_operand"	     "=Ux")
+  [(set (match_operand:MVE_VLD_ST 0 "mve_memory_operand"	     "=Ux")
 	(unspec:MVE_VLD_ST [(match_operand:MVE_VLD_ST 1 "s_register_operand" " w")]
 	 UNSPEC_MISALIGNED_ACCESS))]
   "((TARGET_HAVE_MVE && VALID_MVE_SI_MODE (<MODE>mode))
@@ -10475,7 +10475,7 @@ (define_insn "*movmisalign<mode>_mve_store"
 
 (define_insn "*movmisalign<mode>_mve_load"
   [(set (match_operand:MVE_VLD_ST 0 "s_register_operand"				 "=w")
-	(unspec:MVE_VLD_ST [(match_operand:MVE_VLD_ST 1 "neon_permissive_struct_operand" " Ux")]
+	(unspec:MVE_VLD_ST [(match_operand:MVE_VLD_ST 1 "mve_memory_operand" " Ux")]
 	 UNSPEC_MISALIGNED_ACCESS))]
   "((TARGET_HAVE_MVE && VALID_MVE_SI_MODE (<MODE>mode))
     || (TARGET_HAVE_MVE_FLOAT && VALID_MVE_SF_MODE (<MODE>mode)))
diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md
index fd878cba22d..1fd68f3ac43 100644
--- a/gcc/config/arm/vec-common.md
+++ b/gcc/config/arm/vec-common.md
@@ -280,29 +280,81 @@ (define_expand "cml<fcmac1><conj_op><mode>4"
   DONE;
 })
 
-(define_expand "movmisalign<mode>"
- [(set (match_operand:VDQ 0 "neon_perm_struct_or_reg_operand")
-	(unspec:VDQ [(match_operand:VDQ 1 "neon_perm_struct_or_reg_operand")]
+(define_expand "@movmisalign<mode>"
+ [(set (match_operand:VDQ 0 "nonimmediate_operand")
+	(unspec:VDQ [(match_operand:VDQ 1 "general_operand")]
 	 UNSPEC_MISALIGNED_ACCESS))]
  "ARM_HAVE_<MODE>_LDST && !BYTES_BIG_ENDIAN
   && unaligned_access && !TARGET_REALLY_IWMMXT"
 {
- rtx adjust_mem;
- /* This pattern is not permitted to fail during expansion: if both arguments
-    are non-registers (e.g. memory := constant, which can be created by the
-    auto-vectorizer), force operand 1 into a register.  */
- if (!s_register_operand (operands[0], <MODE>mode)
-     && !s_register_operand (operands[1], <MODE>mode))
-   operands[1] = force_reg (<MODE>mode, operands[1]);
-
- if (s_register_operand (operands[0], <MODE>mode))
-   adjust_mem = operands[1];
- else
-   adjust_mem = operands[0];
-
- /* Legitimize address.  */
- if (!neon_vector_mem_operand (adjust_mem, 2, true))
-   XEXP (adjust_mem, 0) = force_reg (Pmode, XEXP (adjust_mem, 0));
+  rtx *memloc;
+  bool for_store = false;
+  /* This pattern is not permitted to fail during expansion: if both arguments
+     are non-registers (e.g. memory := constant, which can be created by the
+     auto-vectorizer), force operand 1 into a register.  */
+  if (!s_register_operand (operands[0], <MODE>mode)
+      && !s_register_operand (operands[1], <MODE>mode))
+    operands[1] = force_reg (<MODE>mode, operands[1]);
+
+  if (s_register_operand (operands[0], <MODE>mode))
+    memloc = &operands[1];
+  else
+    {
+      memloc = &operands[0];
+      for_store = true;
+    }
+
+  /* For MVE, vector loads/stores must be aligned to the element size.  If the
+     alignment is less than that convert the load/store to a suitable mode.  */
+  if (TARGET_HAVE_MVE
+      && (MEM_ALIGN (*memloc)
+	  < GET_MODE_ALIGNMENT (GET_MODE_INNER (<MODE>mode))))
+    {
+      scalar_mode new_smode;
+      switch (MEM_ALIGN (*memloc))
+	{
+	case 64:
+	case 32:
+	  new_smode = SImode;
+	  break;
+	case 16:
+	  new_smode = HImode;
+	  break;
+	default:
+	  new_smode = QImode;
+	  break;
+	}
+      machine_mode new_mode
+	= mode_for_vector (new_smode,
+			   GET_MODE_SIZE (<MODE>mode)
+			   / GET_MODE_SIZE (new_smode)).require ();
+      rtx new_mem = adjust_address (*memloc, new_mode, 0);
+
+      if (!for_store)
+	{
+	  rtx reg = gen_reg_rtx (new_mode);
+	  emit_insn (gen_movmisalign (new_mode, reg, new_mem));
+	  emit_move_insn (operands[0], gen_lowpart (<MODE>mode, reg));
+	  DONE;
+	}
+      emit_insn (gen_movmisalign (new_mode, new_mem,
+				  gen_lowpart (new_mode, operands[1])));
+      DONE;
+    }
+
+  /* Legitimize address.  */
+  if ((TARGET_HAVE_MVE
+       && !mve_vector_mem_operand (<MODE>mode, XEXP (*memloc, 0), false))
+      || (!TARGET_HAVE_MVE
+	  && !neon_vector_mem_operand (*memloc, 2, false)))
+    {
+      rtx new_mem
+	= replace_equiv_address (*memloc,
+				 force_reg (Pmode, XEXP (*memloc, 0)),
+				 false);
+      gcc_assert (MEM_ALIGN (new_mem) == MEM_ALIGN (*memloc));
+      *memloc = new_mem;
+    }
 })
 
 (define_insn "mve_vshlq_<supf><mode>"

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-05-13 10:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-13 10:28 [committed 1/2] arm: fix some issues in mve_vector_mem_operand Richard Earnshaw
2022-05-13 10:28 ` [committed 2/2] arm: correctly handle misaligned MEMs on MVE [PR105463] Richard Earnshaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).