diff options
| -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 | + | ||
