diff options
author | Khem Raj <raj.khem@gmail.com> | 2025-05-14 14:36:33 -0700 |
---|---|---|
committer | Steve Sakoman <steve@sakoman.com> | 2025-05-23 08:42:34 -0700 |
commit | 19ad025a8ddf64c55e8b083290c1b40c461de51e (patch) | |
tree | 8564fd56adaef7bbaa87a43f3118d5d234d80580 | |
parent | cfd8e09d42f6d5057da1cf766614edf5060e0d11 (diff) | |
download | poky-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.inc | 1 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc/0001-arm-Fix-LDRD-register-overlap-PR117675.patch | 148 |
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 | ||
76 | S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/${SOURCEDIR}" | 77 | S = "${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 @@ | |||
1 | From 9366c328518766d896155388726055624716c0af Mon Sep 17 00:00:00 2001 | ||
2 | From: Wilco Dijkstra <wilco.dijkstra@arm.com> | ||
3 | Date: Tue, 10 Dec 2024 14:22:48 +0000 | ||
4 | Subject: [PATCH] arm: Fix LDRD register overlap [PR117675] | ||
5 | |||
6 | The register indexed variants of LDRD have complex register overlap constraints | ||
7 | which makes them hard to use without using output_move_double (which can't be | ||
8 | used for atomics as it doesn't guarantee to emit atomic LDRD/STRD when required). | ||
9 | Add a new predicate and constraint for plain LDRD/STRD with base or base+imm. | ||
10 | This blocks register indexing and fixes PR117675. | ||
11 | |||
12 | gcc: | ||
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 | |||
21 | gcc/testsuite: | ||
22 | PR target/117675 | ||
23 | * gcc.target/arm/pr117675.c: Add new test. | ||
24 | |||
25 | (cherry picked from commit 21fbfae2e55e1a153820acc6fbd922e66f67e65b) | ||
26 | |||
27 | Upstream-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 | + | ||