Wilco Dijkstra via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> In aarch64_classify_symbol symbols are allowed large offsets on relocations.
> This means the offset can use all of the +/-4GB offset, leaving no offset
> available for the symbol itself.  This results in relocation overflow and
> link-time errors for simple expressions like &global_array + 0xffffff00.
>
> To avoid this, unless the offset_within_block_p is true, limit the offset
> to +/-1MB so that the symbol needs to be within a 3.9GB offset from its
> references.  For the tiny code model use a 64KB offset, allowing most of
> the 1MB range for code/data between the symbol and its references.
>
>     gcc/
>         PR target/98618
>       * config/aarch64/aarch64.c (aarch64_classify_symbol):
>       Apply reasonable limit to symbol offsets.
>
>     testsuite/
>         PR target/98616
>       * gcc.target/aarch64/symbol-range.c: Improve testcase.
>       * gcc.target/aarch64/symbol-range-tiny.c: Likewise.
>
> From-SVN: r277068
> (cherry picked from commit 7d3b27ff12610fde9d6c4b56abc70c6ee9b6b3db)

OK, thanks.  Although it's not a regression, it's a difficult bug to
work around.

Richard

>
> ---
>
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index 
> 5a8acf8607a735d241c8849a449c000996d96931..6a42c06f04730d0bc55294f0eca59b9711952a2e
>  100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,12 @@
> +2021-01-12  Wilco Dijkstra  <wdijk...@arm.com>
> +
> +     Backport from mainline:
> +     2019-10-16  Wilco Dijkstra  <wdijk...@arm.com>
> +
> +     PR target/98618
> +     * config/aarch64/aarch64.c (aarch64_classify_symbol):
> +     Apply reasonable limit to symbol offsets.
> +
>  2021-01-06  2019-07-10  Marc Glisse  <marc.gli...@inria.fr>
>  
>       PR testsuite/90806
> diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
> index 
> 9189777da7e120b9a0912d8501f2da8db144d334..bce50aea01e58f72ab59b30ce43969b48f5ca1b1
>  100644
> --- a/gcc/config/aarch64/aarch64.c
> +++ b/gcc/config/aarch64/aarch64.c
> @@ -13297,26 +13297,31 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT 
> offset)
>            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.  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))
> -           || !IN_RANGE (offset, -1048575, 1048575))
> +          symbol + offset is outside the addressible range of +/-1MB in the
> +          TINY code model.  So we limit the maximum offset to +/-64KB and
> +          assume the offset to the symbol is not larger than +/-(1MB - 64KB).
> +          If offset_within_block_p is true we allow larger offsets.
> +          Furthermore force to memory if the symbol is a weak reference to
> +          something that doesn't resolve to a symbol in this module.  */
> +
> +       if (SYMBOL_REF_WEAK (x) && !aarch64_symbol_binds_local_p (x))
>           return SYMBOL_FORCE_TO_MEM;
> +       if (!(IN_RANGE (offset, -0x10000, 0x10000)
> +             || offset_within_block_p (x, offset)))
> +         return SYMBOL_FORCE_TO_MEM;
> +
>         return SYMBOL_TINY_ABSOLUTE;
>  
>       case AARCH64_CMODEL_SMALL:
>         /* Same reasoning as the tiny code model, but the offset cap here is
> -          4G.  */
> -       if ((SYMBOL_REF_WEAK (x)
> -            && !aarch64_symbol_binds_local_p (x))
> -           || !IN_RANGE (offset, HOST_WIDE_INT_C (-4294967263),
> -                         HOST_WIDE_INT_C (4294967264)))
> +          1MB, allowing +/-3.9GB for the offset to the symbol.  */
> +
> +       if (SYMBOL_REF_WEAK (x) && !aarch64_symbol_binds_local_p (x))
>           return SYMBOL_FORCE_TO_MEM;
> +       if (!(IN_RANGE (offset, -0x100000, 0x100000)
> +             || offset_within_block_p (x, offset)))
> +         return SYMBOL_FORCE_TO_MEM;
> +
>         return SYMBOL_SMALL_ABSOLUTE;
>  
>       case AARCH64_CMODEL_TINY_PIC:
> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
> index 
> 835bf14107ffdef3b700dc00399a2d03e298f062..e25e5d85063e9e5bffa932dccfa19d9ec2550606
>  100644
> --- a/gcc/testsuite/ChangeLog
> +++ b/gcc/testsuite/ChangeLog
> @@ -1,3 +1,12 @@
> +2021-01-12  Wilco Dijkstra  <wdijk...@arm.com>
> +
> +     Backported from mainline:
> +     2019-10-16  Wilco Dijkstra  <wdijk...@arm.com>
> +
> +     PR target/98618
> +     * gcc.target/aarch64/symbol-range.c: Improve testcase.
> +     * gcc.target/aarch64/symbol-range-tiny.c: Likewise.
> +
>  2021-01-07  Paul Thomas  <pa...@gcc.gnu.org>
>  
>       Backported from master:
> diff --git a/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c 
> b/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c
> index 
> d7e46b059e41f2672b3a1da5506fa8944e752e01..fc6a4f3ec780d9fa86de1c8e1a42a55992ee8b2d
>  100644
> --- a/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c
> +++ b/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c
> @@ -1,12 +1,12 @@
> -/* { dg-do compile } */
> +/* { dg-do link } */
>  /* { dg-options "-O3 -save-temps -mcmodel=tiny" } */
>  
> -int fixed_regs[0x00200000];
> +char fixed_regs[0x00080000];
>  
>  int
> -foo()
> +main ()
>  {
> -  return fixed_regs[0x00080000];
> +  return fixed_regs[0x000ff000];
>  }
>  
>  /* { dg-final { scan-assembler-not "adr\tx\[0-9\]+, fixed_regs\\\+" } } */
> diff --git a/gcc/testsuite/gcc.target/aarch64/symbol-range.c 
> b/gcc/testsuite/gcc.target/aarch64/symbol-range.c
> index 
> 6574cf4310430b847e77ea56bf8f20ef312d53e4..d8e82fa1b2829fd300b6ccf7f80241e5573e7e17
>  100644
> --- a/gcc/testsuite/gcc.target/aarch64/symbol-range.c
> +++ b/gcc/testsuite/gcc.target/aarch64/symbol-range.c
> @@ -1,12 +1,12 @@
> -/* { dg-do compile } */
> +/* { dg-do link } */
>  /* { dg-options "-O3 -save-temps -mcmodel=small" } */
>  
> -int fixed_regs[0x200000000ULL];
> +char fixed_regs[0x80000000];
>  
>  int
> -foo()
> +main ()
>  {
> -  return fixed_regs[0x100000000ULL];
> +  return fixed_regs[0xfffff000];
>  }
>  
>  /* { dg-final { scan-assembler-not "adrp\tx\[0-9\]+, fixed_regs\\\+" } } */

Reply via email to