]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Arm: Fix disassembly error in Thumb-1 relaxed load/store [PR115188]
authorWilco Dijkstra <wilco.dijkstra@arm.com>
Tue, 2 Jul 2024 16:37:04 +0000 (17:37 +0100)
committerWilco Dijkstra <wilco.dijkstra@arm.com>
Tue, 2 Jul 2024 17:01:56 +0000 (18:01 +0100)
A Thumb-1 memory operand allows single-register LDMIA/STMIA. This doesn't get
printed as LDR/STR with writeback in unified syntax, resulting in strange
assembler errors if writeback is selected.  To work around this, use the 'Uw'
constraint that blocks writeback.  Also use a new 'mem_and_no_t1_wback_op'
which is a general memory operand that disallows writeback in Thumb-1.
A few other patterns were using 'm' for Thumb-1 in a similar way, update these
to also use 'mem_and_no_t1_wback_op' and 'Uw'.

gcc:
PR target/115188
* config/arm/arm.md (unaligned_loadsi): Use 'Uw' constraint and
'mem_and_no_t1_wback_op'.
(unaligned_loadhiu): Likewise.
(unaligned_storesi): Likewise.
(unaligned_storehi): Likewise.
* config/arm/predicates.md (mem_and_no_t1_wback_op): Add new predicate.
* config/arm/sync.md (arm_atomic_load<mode>): Use 'Uw' constraint.
(arm_atomic_store<mode>): Likewise.

gcc/testsuite:
PR target/115188
* gcc.target/arm/pr115188.c: Add new test.

gcc/config/arm/arm.md
gcc/config/arm/predicates.md
gcc/config/arm/sync.md
gcc/testsuite/gcc.target/arm/pr115188.c [new file with mode: 0644]

index f47e036a8034ed16c61bbd753c7a7cd3efb1ecbd..aae47897199ebd48d3acda86829d485114758700 100644 (file)
 
 (define_insn "unaligned_loadsi"
   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
-       (unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")]
+       (unspec:SI [(match_operand:SI 1 "mem_and_no_t1_wback_op" "Uw,Uw,m")]
                   UNSPEC_UNALIGNED_LOAD))]
   "unaligned_access"
   "@
 (define_insn "unaligned_loadhiu"
   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
        (zero_extend:SI
-         (unspec:HI [(match_operand:HI 1 "memory_operand" "m,Uw,m")]
+         (unspec:HI [(match_operand:HI 1 "mem_and_no_t1_wback_op" "Uw,Uw,m")]
                     UNSPEC_UNALIGNED_LOAD)))]
   "unaligned_access"
   "@
    (set_attr "type" "store_8")])
 
 (define_insn "unaligned_storesi"
-  [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m")
+  [(set (match_operand:SI 0 "mem_and_no_t1_wback_op" "=Uw,Uw,m")
        (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")]
                   UNSPEC_UNALIGNED_STORE))]
   "unaligned_access"
    (set_attr "type" "store_4")])
 
 (define_insn "unaligned_storehi"
-  [(set (match_operand:HI 0 "memory_operand" "=m,Uw,m")
+  [(set (match_operand:HI 0 "mem_and_no_t1_wback_op" "=Uw,Uw,m")
        (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,l,r")]
                   UNSPEC_UNALIGNED_STORE))]
   "unaligned_access"
index 4994c0c57d6431117c16f7a05e800821dee93408..197054b611892006e7df97a4480b349a55a31f07 100644 (file)
 ;; A special predicate that doesn't match a particular mode.
 (define_special_predicate "arm_any_register_operand"
   (match_code "reg"))
+
+;; General memory operand that disallows Thumb-1 POST_INC.
+(define_predicate "mem_and_no_t1_wback_op"
+  (and (match_operand 0 "memory_operand")
+       (match_test "!(TARGET_THUMB1 && GET_CODE (XEXP (op, 0)) == POST_INC)")))
index df8dbe170cacb6b60d56a6f19aadd5a6c9c51f7a..0a8347fc5980845642d39bcbe0ef18f97cc446e4 100644 (file)
@@ -65,7 +65,7 @@
 (define_insn "arm_atomic_load<mode>"
   [(set (match_operand:QHSI 0 "register_operand" "=r,l")
     (unspec_volatile:QHSI
-      [(match_operand:QHSI 1 "memory_operand" "m,m")]
+      [(match_operand:QHSI 1 "mem_and_no_t1_wback_op" "m,Uw")]
       VUNSPEC_LDR))]
   ""
   "ldr<sync_sfx>\t%0, %1"
@@ -81,7 +81,7 @@
 )
 
 (define_insn "arm_atomic_store<mode>"
-  [(set (match_operand:QHSI 0 "memory_operand" "=m,m")
+  [(set (match_operand:QHSI 0 "mem_and_no_t1_wback_op" "=m,Uw")
     (unspec_volatile:QHSI
       [(match_operand:QHSI 1 "register_operand" "r,l")]
       VUNSPEC_STR))]
diff --git a/gcc/testsuite/gcc.target/arm/pr115188.c b/gcc/testsuite/gcc.target/arm/pr115188.c
new file mode 100644 (file)
index 0000000..9a4022b
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_arch_v6m_ok }
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_arch_v6m } */
+
+void init (int *p, int n)
+{
+  for (int i = 0; i < n; i++)
+    __atomic_store_4 (p + i, 0, __ATOMIC_RELAXED);
+}