summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKhem Raj <raj.khem@gmail.com>2025-05-14 14:36:33 -0700
committerSteve Sakoman <steve@sakoman.com>2025-05-23 08:42:34 -0700
commit19ad025a8ddf64c55e8b083290c1b40c461de51e (patch)
tree8564fd56adaef7bbaa87a43f3118d5d234d80580
parentcfd8e09d42f6d5057da1cf766614edf5060e0d11 (diff)
downloadpoky-19ad025a8ddf64c55e8b083290c1b40c461de51e.tar.gz
gcc: Fix LDRD register overlap in register-indexed mode
Issue is seen with nodejs ending with Illegal instruction on OE Its also in QT5base and perhaps many other packages using 64bit atomics. Thanks to jeroen (oe IRC) to report and help reduce the problem. (From OE-Core rev: bd62158946e214076686e0709d24771acb60665f) Signed-off-by: Khem Raj <raj.khem@gmail.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/recipes-devtools/gcc/gcc-14.2.inc1
-rw-r--r--meta/recipes-devtools/gcc/gcc/0001-arm-Fix-LDRD-register-overlap-PR117675.patch148
2 files changed, 149 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-14.2.inc b/meta/recipes-devtools/gcc/gcc-14.2.inc
index 3d65bed92a..f4e364f692 100644
--- a/meta/recipes-devtools/gcc/gcc-14.2.inc
+++ b/meta/recipes-devtools/gcc/gcc-14.2.inc
@@ -71,6 +71,7 @@ SRC_URI = "${BASEURI} \
71 file://0026-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch \ 71 file://0026-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch \
72 file://0027-gcc-backport-patch-to-fix-data-relocation-to-ENDBR-s.patch \ 72 file://0027-gcc-backport-patch-to-fix-data-relocation-to-ENDBR-s.patch \
73 file://gcc.git-ab884fffe3fc82a710bea66ad651720d71c938b8.patch \ 73 file://gcc.git-ab884fffe3fc82a710bea66ad651720d71c938b8.patch \
74 file://0001-arm-Fix-LDRD-register-overlap-PR117675.patch \
74" 75"
75 76
76S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/${SOURCEDIR}" 77S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/${SOURCEDIR}"
diff --git a/meta/recipes-devtools/gcc/gcc/0001-arm-Fix-LDRD-register-overlap-PR117675.patch b/meta/recipes-devtools/gcc/gcc/0001-arm-Fix-LDRD-register-overlap-PR117675.patch
new file mode 100644
index 0000000000..e3d887a135
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc/0001-arm-Fix-LDRD-register-overlap-PR117675.patch
@@ -0,0 +1,148 @@
1From 9366c328518766d896155388726055624716c0af Mon Sep 17 00:00:00 2001
2From: Wilco Dijkstra <wilco.dijkstra@arm.com>
3Date: Tue, 10 Dec 2024 14:22:48 +0000
4Subject: [PATCH] arm: Fix LDRD register overlap [PR117675]
5
6The register indexed variants of LDRD have complex register overlap constraints
7which makes them hard to use without using output_move_double (which can't be
8used for atomics as it doesn't guarantee to emit atomic LDRD/STRD when required).
9Add a new predicate and constraint for plain LDRD/STRD with base or base+imm.
10This blocks register indexing and fixes PR117675.
11
12gcc:
13 PR target/117675
14 * config/arm/arm.cc (arm_ldrd_legitimate_address): New function.
15 * config/arm/arm-protos.h (arm_ldrd_legitimate_address): New prototype.
16 * config/arm/constraints.md: Add new Uo constraint.
17 * config/arm/predicates.md (arm_ldrd_memory_operand): Add new predicate.
18 * config/arm/sync.md (arm_atomic_loaddi2_ldrd): Use
19 arm_ldrd_memory_operand and Uo.
20
21gcc/testsuite:
22 PR target/117675
23 * gcc.target/arm/pr117675.c: Add new test.
24
25(cherry picked from commit 21fbfae2e55e1a153820acc6fbd922e66f67e65b)
26
27Upstream-Status: Backport [https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117675]
28---
29 gcc/config/arm/arm-protos.h | 1 +
30 gcc/config/arm/arm.cc | 24 ++++++++++++++++++++++++
31 gcc/config/arm/constraints.md | 8 +++++++-
32 gcc/config/arm/predicates.md | 4 ++++
33 gcc/config/arm/sync.md | 2 +-
34 gcc/testsuite/gcc.target/arm/pr117675.c | 17 +++++++++++++++++
35 6 files changed, 54 insertions(+), 2 deletions(-)
36 create mode 100644 gcc/testsuite/gcc.target/arm/pr117675.c
37
38--- a/gcc/config/arm/arm-protos.h
39+++ b/gcc/config/arm/arm-protos.h
40@@ -202,6 +202,7 @@ extern rtx arm_load_tp (rtx);
41 extern bool arm_coproc_builtin_available (enum unspecv);
42 extern bool arm_coproc_ldc_stc_legitimate_address (rtx);
43 extern rtx arm_stack_protect_tls_canary_mem (bool);
44+extern bool arm_ldrd_legitimate_address (rtx);
45
46
47 #if defined TREE_CODE
48--- a/gcc/config/arm/arm.cc
49+++ b/gcc/config/arm/arm.cc
50@@ -34523,6 +34523,30 @@ arm_coproc_ldc_stc_legitimate_address (r
51 return false;
52 }
53
54+/* Return true if OP is a valid memory operand for LDRD/STRD without any
55+ register overlap restrictions. Allow [base] and [base, imm] for now. */
56+bool
57+arm_ldrd_legitimate_address (rtx op)
58+{
59+ if (!MEM_P (op))
60+ return false;
61+
62+ op = XEXP (op, 0);
63+ if (REG_P (op))
64+ return true;
65+
66+ if (GET_CODE (op) != PLUS)
67+ return false;
68+ if (!REG_P (XEXP (op, 0)) || !CONST_INT_P (XEXP (op, 1)))
69+ return false;
70+
71+ HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
72+
73+ if (TARGET_ARM)
74+ return IN_RANGE (val, -255, 255);
75+ return IN_RANGE (val, -1020, 1020) && (val & 3) == 0;
76+}
77+
78 /* Return the diagnostic message string if conversion from FROMTYPE to
79 TOTYPE is not allowed, NULL otherwise. */
80
81--- a/gcc/config/arm/constraints.md
82+++ b/gcc/config/arm/constraints.md
83@@ -39,7 +39,7 @@
84 ;; in all states: Pg
85
86 ;; The following memory constraints have been used:
87-;; in ARM/Thumb-2 state: Uh, Ut, Uv, Uy, Un, Um, Us, Up, Uf, Ux, Ul
88+;; in ARM/Thumb-2 state: Uh, Ut, Uv, Uy, Un, Um, Us, Uo, Up, Uf, Ux, Ul, Uz
89 ;; in ARM state: Uq
90 ;; in Thumb state: Uu, Uw
91 ;; in all states: Q
92@@ -585,6 +585,12 @@
93 (and (match_code "mem")
94 (match_test "arm_coproc_ldc_stc_legitimate_address (op)")))
95
96+(define_memory_constraint "Uo"
97+ "@internal
98+ A memory operand for Arm/Thumb-2 LDRD/STRD"
99+ (and (match_code "mem")
100+ (match_test "arm_ldrd_legitimate_address (op)")))
101+
102 ;; We used to have constraint letters for S and R in ARM state, but
103 ;; all uses of these now appear to have been removed.
104
105--- a/gcc/config/arm/predicates.md
106+++ b/gcc/config/arm/predicates.md
107@@ -849,6 +849,10 @@
108 (and (match_operand 0 "memory_operand")
109 (match_code "reg" "0")))
110
111+;; True if the operand is memory reference suitable for a ldrd/strd.
112+(define_predicate "arm_ldrd_memory_operand"
113+ (match_test "arm_ldrd_legitimate_address (op)"))
114+
115 ;; Predicates for parallel expanders based on mode.
116 (define_special_predicate "vect_par_constant_high"
117 (match_code "parallel")
118--- a/gcc/config/arm/sync.md
119+++ b/gcc/config/arm/sync.md
120@@ -161,7 +161,7 @@
121 (define_insn "arm_atomic_loaddi2_ldrd"
122 [(set (match_operand:DI 0 "register_operand" "=r")
123 (unspec_volatile:DI
124- [(match_operand:DI 1 "memory_operand" "m")]
125+ [(match_operand:DI 1 "arm_ldrd_memory_operand" "Uo")]
126 VUNSPEC_LDRD_ATOMIC))]
127 "ARM_DOUBLEWORD_ALIGN && TARGET_HAVE_LPAE"
128 "ldrd\t%0, %H0, %1"
129--- /dev/null
130+++ b/gcc/testsuite/gcc.target/arm/pr117675.c
131@@ -0,0 +1,17 @@
132+/* { dg-do compile } */
133+/* { dg-options "-O2 -marm" } */
134+/* { dg-require-effective-target arm_arch_v7ve_neon_ok } */
135+/* { dg-add-options arm_arch_v7ve_neon } */
136+/* { dg-final { check-function-bodies "**" "" "" } } */
137+
138+/*
139+** f1:
140+** add r0, r0, r1
141+** ldrd r0, r1, \[r0\]
142+** bx lr
143+*/
144+long long f1 (char *p, int i)
145+{
146+ return __atomic_load_n ((long long *)(p + i), __ATOMIC_RELAXED);
147+}
148+