[AArch64] Fix PR target/63874
authorRamana Radhakrishnan <ramana.radhakrishnan@arm.com>
Mon, 4 Jul 2016 09:06:02 +0000 (09:06 +0000)
committerRamana Radhakrishnan <ramana@gcc.gnu.org>
Mon, 4 Jul 2016 09:06:02 +0000 (09:06 +0000)
     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

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/pr63874.c [new file with mode: 0644]

index d5abcd15a588cbfc6e0392a920e35d3fb4055335..c021b34409bf5f049c818d8548acdcbed6877d50 100644 (file)
@@ -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>
 
index 062899fbcc8840769cc09bef6194e546bc813e86..512ef10d158d2eaa1384d28c43b9a8f90387099d 100644 (file)
@@ -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;
index 86c1b5d373b2d93d3a24a8b303c7ea5521d8d2ad..23e010ed834af32f0ddf98c67833924858045946 100644 (file)
@@ -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 (file)
index 0000000..1a745a0
--- /dev/null
@@ -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" } } */