aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorStam Markianos-Wright <stam.markianos-wright@arm.com>2022-12-30 11:25:22 +0000
committerStam Markianos-Wright <stam.markianos-wright@arm.com>2022-12-30 11:25:22 +0000
commit4269a6567eb991e6838f40bda5be9e3a7972530c (patch)
treee589a6ae298d1f29b704bef1055a405eae8d3c86 /gcc/config
parentcdc6bf44eec295805ae29a8aaddafd111de01c8e (diff)
downloadgcc-4269a6567eb991e6838f40bda5be9e3a7972530c.zip
gcc-4269a6567eb991e6838f40bda5be9e3a7972530c.tar.gz
gcc-4269a6567eb991e6838f40bda5be9e3a7972530c.tar.bz2
Fix memory constraint on MVE v[ld/st][2/4] instructions [PR107714]
In the M-Class Arm-ARM: https://developer.arm.com/documentation/ddi0553/bu/?lang=en these MVE instructions only have '!' writeback variant and at: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107714 we found that the Um constraint would also allow through a register offset writeback, resulting in an assembler error. Here I have added a new constraint and predicate for these instructions, which (uniquely, AFAICT), only support a `!` writeback increment by the data size (inside the compiler this is a POST_INC). No regressions in arm-none-eabi with MVE and MVE.FP. gcc/ChangeLog: PR target/107714 * config/arm/arm-protos.h (mve_struct_mem_operand): New protoype. * config/arm/arm.cc (mve_struct_mem_operand): New function. * config/arm/constraints.md (Ug): New constraint. * config/arm/mve.md (mve_vst4q<mode>): Change constraint. (mve_vst2q<mode>): Likewise. (mve_vld4q<mode>): Likewise. (mve_vld2q<mode>): Likewise. * config/arm/predicates.md (mve_struct_operand): New predicate. gcc/testsuite/ChangeLog: PR target/107714 * gcc.target/arm/mve/intrinsics/vldst24q_reg_offset.c: New test.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.cc18
-rw-r--r--gcc/config/arm/constraints.md5
-rw-r--r--gcc/config/arm/mve.md8
-rw-r--r--gcc/config/arm/predicates.md4
5 files changed, 32 insertions, 4 deletions
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 550272f..8ea3811 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -122,6 +122,7 @@ extern int arm_coproc_mem_operand_wb (rtx, int);
extern int neon_vector_mem_operand (rtx, int, bool);
extern int mve_vector_mem_operand (machine_mode, rtx, bool);
extern int neon_struct_mem_operand (rtx);
+extern int mve_struct_mem_operand (rtx);
extern rtx *neon_vcmla_lane_prepare_operands (rtx *);
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index b587561..31f2a7b 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -13737,6 +13737,24 @@ neon_vector_mem_operand (rtx op, int type, bool strict)
return FALSE;
}
+/* Return TRUE if OP is a mem suitable for loading/storing an MVE struct
+ type. */
+int
+mve_struct_mem_operand (rtx op)
+{
+ rtx ind = XEXP (op, 0);
+
+ /* Match: (mem (reg)). */
+ if (REG_P (ind))
+ return arm_address_register_rtx_p (ind, 0);
+
+ /* Allow only post-increment by the mode size. */
+ if (GET_CODE (ind) == POST_INC)
+ return arm_address_register_rtx_p (XEXP (ind, 0), 0);
+
+ return FALSE;
+}
+
/* Return TRUE if OP is a mem suitable for loading/storing a Neon struct
type. */
int
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index e5a36d2..121ec05 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -474,6 +474,11 @@
(and (match_code "mem")
(match_test "TARGET_32BIT && arm_coproc_mem_operand (op, FALSE)")))
+(define_memory_constraint "Ug"
+ "@internal
+ In Thumb-2 state a valid MVE struct load/store address."
+ (match_operand 0 "mve_struct_operand"))
+
(define_memory_constraint "Uj"
"@internal
In ARM/Thumb-2 state a VFP load/store address that supports writeback
diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 3fe9db8..0c21db1 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -99,7 +99,7 @@
;; [vst4q])
;;
(define_insn "mve_vst4q<mode>"
- [(set (match_operand:XI 0 "neon_struct_operand" "=Um")
+ [(set (match_operand:XI 0 "mve_struct_operand" "=Ug")
(unspec:XI [(match_operand:XI 1 "s_register_operand" "w")
(unspec:MVE_VLD_ST [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
VST4Q))
@@ -9961,7 +9961,7 @@
;; [vst2q])
;;
(define_insn "mve_vst2q<mode>"
- [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
+ [(set (match_operand:OI 0 "mve_struct_operand" "=Ug")
(unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
(unspec:MVE_VLD_ST [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
VST2Q))
@@ -9990,7 +9990,7 @@
;;
(define_insn "mve_vld2q<mode>"
[(set (match_operand:OI 0 "s_register_operand" "=w")
- (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um")
+ (unspec:OI [(match_operand:OI 1 "mve_struct_operand" "Ug")
(unspec:MVE_VLD_ST [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
VLD2Q))
]
@@ -10018,7 +10018,7 @@
;;
(define_insn "mve_vld4q<mode>"
[(set (match_operand:XI 0 "s_register_operand" "=w")
- (unspec:XI [(match_operand:XI 1 "neon_struct_operand" "Um")
+ (unspec:XI [(match_operand:XI 1 "mve_struct_operand" "Ug")
(unspec:MVE_VLD_ST [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
VLD4Q))
]
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index aab5a91..67f2fdb 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -876,6 +876,10 @@
(and (match_code "mem")
(match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2, true)")))
+(define_predicate "mve_struct_operand"
+ (and (match_code "mem")
+ (match_test "TARGET_HAVE_MVE && mve_struct_mem_operand (op)")))
+
(define_predicate "neon_permissive_struct_operand"
(and (match_code "mem")
(match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2, false)")))