aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2024-07-22 16:42:15 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2024-07-22 16:42:15 +0100
commitebde0cc101a3b26bc8c188e0d2f79b649bacc43a (patch)
tree07e389951bfe4fb34ed84a1a8012a827915fe50b
parent88d16194d0c8a6bdc2896c8944bfbf3e6038c9d2 (diff)
downloadgcc-ebde0cc101a3b26bc8c188e0d2f79b649bacc43a.zip
gcc-ebde0cc101a3b26bc8c188e0d2f79b649bacc43a.tar.gz
gcc-ebde0cc101a3b26bc8c188e0d2f79b649bacc43a.tar.bz2
aarch64: Tighten aarch64_simd_mem_operand_p [PR115969]
aarch64_simd_mem_operand_p checked for a memory with a POST_INC or REG address, but it didn't check what kind of register was being used. This meant that it allowed DImode FPRs as well as GPRs. I wondered about rewriting it to use aarch64_classify_address, but this one-line fix seemed simpler. The structure then mirrors the existing early exit in aarch64_classify_address itself: /* On LE, for AdvSIMD, don't support anything other than POST_INC or REG addressing. */ if (advsimd_struct_p && TARGET_SIMD && !BYTES_BIG_ENDIAN && (code != POST_INC && code != REG)) return false; gcc/ PR target/115969 * config/aarch64/aarch64.cc (aarch64_simd_mem_operand_p): Require the operand to be a legitimate memory_operand. gcc/testsuite/ PR target/115969 * gcc.target/aarch64/pr115969.c: New test.
-rw-r--r--gcc/config/aarch64/aarch64.cc5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr115969.c8
2 files changed, 11 insertions, 2 deletions
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 89eb6634..9e51236 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -23377,8 +23377,9 @@ aarch64_endian_lane_rtx (machine_mode mode, unsigned int n)
bool
aarch64_simd_mem_operand_p (rtx op)
{
- return MEM_P (op) && (GET_CODE (XEXP (op, 0)) == POST_INC
- || REG_P (XEXP (op, 0)));
+ return (MEM_P (op)
+ && (GET_CODE (XEXP (op, 0)) == POST_INC || REG_P (XEXP (op, 0)))
+ && memory_operand (op, VOIDmode));
}
/* Return true if OP is a valid MEM operand for an SVE LD1R instruction. */
diff --git a/gcc/testsuite/gcc.target/aarch64/pr115969.c b/gcc/testsuite/gcc.target/aarch64/pr115969.c
new file mode 100644
index 0000000..ea46626
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr115969.c
@@ -0,0 +1,8 @@
+/* { dg-options "-O2" } */
+
+#define vec8 __attribute__((vector_size(8)))
+vec8 int f(int *a)
+{
+ asm("":"+w"(a));
+ return (vec8 int){a[0], a[0]};
+}