This has been in my patch stack for quite some time. The problem here was that we weren't handling arm_word_relocations in arm_valid_symbolic_address and is the surest fix for this for GCC8 and GCC7.
Regression tested on arm-none-linux-gnueabihf . Applying to trunk and backporting to GCC-7 in a day or so. regards Ramana * config/arm/arm.c (arm_valid_symbolic_address): Handle arm_word_relocations gcc/testsuite * gcc.target/arm/pr81863.c: New test.
commit 22e3c20b7e6b5027f07b71ca31c9f65e66537b0b Author: Ramana Radhakrishnan <ramana.radhakrish...@arm.com> Date: Tue Mar 13 10:54:04 2018 +0000 [Patch ARM] Fix PR81863. This has been in my patch stack for quite some time. The problem here was that we weren't handling arm_word_relocations in arm_valid_symbolic_address and is the surest fix for this for GCC8 and GCC7. Regression tested on arm-none-linux-gnueabihf . Applying to trunk and GCC-7 * config/arm/arm.c (arm_valid_symbolic_address): Handle arm_word_relocations gcc/testsuite * gcc.target/arm/pr81863.c: New test. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 90d62e6..09795d3 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -29773,6 +29773,9 @@ arm_valid_symbolic_address_p (rtx addr) rtx xop0, xop1 = NULL_RTX; rtx tmp = addr; + if (target_word_relocations) + return false; + if (GET_CODE (tmp) == SYMBOL_REF || GET_CODE (tmp) == LABEL_REF) return true; diff --git a/gcc/testsuite/gcc.target/arm/pr81863.c b/gcc/testsuite/gcc.target/arm/pr81863.c new file mode 100644 index 0000000..63b1ed6 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr81863.c @@ -0,0 +1,44 @@ +/* testsuite/gcc.target/arm/pr48183.c */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mword-relocations -march=armv7-a -marm" } */ +/* { dg-final { scan-assembler-not "\[\\t \]+movw" } } */ + +int a, d, f; +long b; +struct ww_class { + int stamp; +} c; +struct stress { + int locks; + int nlocks; +}; +void *e; +int atomic_add_return_relaxed(int *p1) { + __builtin_prefetch(p1); + return a; +} +void atomic_long_inc_return_relaxed(int *p1) { + int *v = p1; + atomic_add_return_relaxed(v); +} +void ww_acquire_init(struct ww_class *p1) { + atomic_long_inc_return_relaxed(&p1->stamp); +} +void ww_mutex_lock(); +int *get_random_order(); +void stress_inorder_work() { + struct stress *g = e; + int h = g->nlocks; + int *i = &g->locks, *j = get_random_order(); + do { + int n; + ww_acquire_init(&c); + retry: + for (n = 0; n < h; n++) + ww_mutex_lock(i[j[n]]); + f = n; + if (d) + goto retry; + } while (b); +} +