https://gcc.gnu.org/g:e5bb7a328eb71daa02d15b48d3a6c6b8cd24abc5

commit r16-733-ge5bb7a328eb71daa02d15b48d3a6c6b8cd24abc5
Author: Richard Earnshaw <rearn...@arm.com>
Date:   Mon May 19 16:19:39 2025 +0100

    arm: fully validate mem_noofs_operand [PR120351]
    
    It's not enough to just check that a memory operand is of the form
    mem(reg); after RA we also need to validate the register being used.
    The safest way to do this is to call memory_operand.
    
            PR target/120351
    
    gcc/ChangeLog:
    
            * config/arm/predicates.md (mem_noofs_operand): Also check the op
            is a valid memory_operand.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/arm/pr120351.c: New test.

Diff:
---
 gcc/config/arm/predicates.md            |  3 ++-
 gcc/testsuite/gcc.target/arm/pr120351.c | 47 +++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 57d4ec660886..c683ec2c607f 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -901,7 +901,8 @@
 
 (define_predicate "mem_noofs_operand"
   (and (match_code "mem")
-       (match_code "reg" "0")))
+       (match_code "reg" "0")
+       (match_operand 0 "memory_operand")))
 
 (define_predicate "call_insn_operand"
   (ior (and (match_code "symbol_ref")
diff --git a/gcc/testsuite/gcc.target/arm/pr120351.c 
b/gcc/testsuite/gcc.target/arm/pr120351.c
new file mode 100644
index 000000000000..d8e9d73275ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr120351.c
@@ -0,0 +1,47 @@
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-add-options arm_neon } */
+/* { dg-additional-options "-O2" } */
+
+
+typedef struct A
+{
+  int f1;
+} A;
+
+__inline void ref (A* x)
+{
+  __atomic_fetch_add(&x->f1, 1, 0);
+}
+
+typedef struct B
+{
+  A *d;
+  int *ptr;
+} B;
+
+void insertOne (B*, B*);
+
+void init (B *);
+__inline void copy (B *p, B *q)
+{
+  p->d  = q->d;
+  p->ptr = q->ptr;
+  ref (p->d);
+}
+
+__inline void emplace(B* x)
+{
+  B dummy;
+  B _tmp;
+  init (&dummy);
+  copy (&_tmp, &dummy);
+  insertOne(x, &_tmp);
+}
+
+void testing ()
+{
+  B test;
+  init (&test);
+  emplace(&test);
+}

Reply via email to