aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRamana Radhakrishnan <ramana.radhakrishnan@arm.com>2016-07-04 09:06:02 +0000
committerRamana Radhakrishnan <ramana@gcc.gnu.org>2016-07-04 09:06:02 +0000
commit15f6e0dac34a243341fba80f8ebdaeec78d766fe (patch)
treee92d0a15a4459d3e662684de30d415d75d78ffa8 /gcc
parentc61465bda5ed50a1bf664211515436f884e6fa66 (diff)
downloadgcc-15f6e0dac34a243341fba80f8ebdaeec78d766fe.zip
gcc-15f6e0dac34a243341fba80f8ebdaeec78d766fe.tar.gz
gcc-15f6e0dac34a243341fba80f8ebdaeec78d766fe.tar.bz2
[AArch64] Fix PR target/63874
In this PR we have a situation where we aren't really detecting weak references vs weak definitions. If one has a weak definition that binds locally there's no reason not to put out PC relative relocations. However if you have a genuine weak reference that is known not to bind locally it makes very little sense to put out an entry into the literal pool which doesn't always work with DSOs and shared objects. Tested aarch64-none-linux-gnu bootstrap and regression test with no regressions 2016-07-04 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> PR target/63874 * config/aarch64/aarch64.c (aarch64_classify_symbol): Fix typo in comment. Only force to memory if it is a weak external reference. 2016-07-04 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> PR target/63874 * gcc.target/aarch64/pr63874.c: New test. From-SVN: r237957
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/aarch64/aarch64.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr63874.c22
4 files changed, 42 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d5abcd1..c021b34 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2016-07-04 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ PR target/63874
+ * config/aarch64/aarch64.c (aarch64_classify_symbol): Fix
+ typo in comment. Only force to memory if it is a weak
+ external reference.
+
2016-07-04 Matthew Wahab <matthew.wahab@arm.com>
Jiong Wang <jiong.wang@arm.com>
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 062899f..512ef10 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -9423,15 +9423,18 @@ aarch64_classify_symbol (rtx x, rtx offset)
switch (aarch64_cmodel)
{
case AARCH64_CMODEL_TINY:
- /* When we retreive symbol + offset address, we have to make sure
+ /* When we retrieve symbol + offset address, we have to make sure
the offset does not cause overflow of the final address. But
we have no way of knowing the address of symbol at compile time
so we can't accurately say if the distance between the PC and
symbol + offset is outside the addressible range of +/-1M in the
TINY code model. So we rely on images not being greater than
1M and cap the offset at 1M and anything beyond 1M will have to
- be loaded using an alternative mechanism. */
- if (SYMBOL_REF_WEAK (x)
+ be loaded using an alternative mechanism. Furthermore if the
+ symbol is a weak reference to something that isn't known to
+ resolve to a symbol in this module, then force to memory. */
+ if ((SYMBOL_REF_WEAK (x)
+ && !aarch64_symbol_binds_local_p (x))
|| INTVAL (offset) < -1048575 || INTVAL (offset) > 1048575)
return SYMBOL_FORCE_TO_MEM;
return SYMBOL_TINY_ABSOLUTE;
@@ -9439,7 +9442,8 @@ aarch64_classify_symbol (rtx x, rtx offset)
case AARCH64_CMODEL_SMALL:
/* Same reasoning as the tiny code model, but the offset cap here is
4G. */
- if (SYMBOL_REF_WEAK (x)
+ if ((SYMBOL_REF_WEAK (x)
+ && !aarch64_symbol_binds_local_p (x))
|| !IN_RANGE (INTVAL (offset), HOST_WIDE_INT_C (-4294967263),
HOST_WIDE_INT_C (4294967264)))
return SYMBOL_FORCE_TO_MEM;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 86c1b5d..23e010e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-07-04 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ PR target/63874
+ * gcc.target/aarch64/pr63874.c: New test.
+
2016-07-04 Jan Beulich <jbeulich@suse.com>
* g++.dg/header.c: New.
diff --git a/gcc/testsuite/gcc.target/aarch64/pr63874.c b/gcc/testsuite/gcc.target/aarch64/pr63874.c
new file mode 100644
index 0000000..1a745a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr63874.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "Not applicable for mcmodel=large" { aarch64*-*-* } { "-mcmodel=large" } { "" } } */
+
+extern void __attribute__((weak)) foo_weakref (void);
+void __attribute__((weak, noinline)) bar (void)
+{
+ return;
+}
+void (*f) (void);
+void (*g) (void);
+
+int
+main (void)
+{
+ f = &foo_weakref;
+ g = &bar;
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "adr*foo_weakref" } } */
+/* { dg-final { scan-assembler-not "\\.(word|xword)\tbar" } } */