Wilco Dijkstra <wilco.dijks...@arm.com> writes: > ping > > In aarch64_classify_symbol symbols are allowed full-range 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_char + 0xffffff00.
If global_char really is a char then isn't that UB? I guess we still have to compile it without error though... > To avoid this, 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. These new values seem a bit magical. Would it work for the original testcase to use FORCE_TO_MEM if !offset_within_block_p (x, offset)? Richard > Bootstrapped on AArch64, passes regress, OK for commit? > > ChangeLog: > 2018-11-09 Wilco Dijkstra <wdijk...@arm.com> > > gcc/ > * config/aarch64/aarch64.c (aarch64_classify_symbol): > Apply reasonable limit to symbol offsets. > > testsuite/ > * gcc.target/aarch64/symbol-range.c (foo): Set new limit. > * gcc.target/aarch64/symbol-range-tiny.c (foo): Likewise. > > -- > > diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c > index > 83453d03095018eddd1801e71ef3836849267444..0023cb37bbae5afe9387840c1bb6b43586d4fac2 > 100644 > --- a/gcc/config/aarch64/aarch64.c > +++ b/gcc/config/aarch64/aarch64.c > @@ -13047,26 +13047,26 @@ 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. */ > + 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). > + 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)) > - || !IN_RANGE (offset, -1048575, 1048575)) > + || !IN_RANGE (offset, -0x10000, 0x10000)) > 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. */ > + 1MB, allowing +/-3.9GB for the offset to the symbol. */ > if ((SYMBOL_REF_WEAK (x) > && !aarch64_symbol_binds_local_p (x)) > - || !IN_RANGE (offset, HOST_WIDE_INT_C (-4294967263), > - HOST_WIDE_INT_C (4294967264))) > + || !IN_RANGE (offset, -0x100000, 0x100000)) > return SYMBOL_FORCE_TO_MEM; > + > return SYMBOL_SMALL_ABSOLUTE; > > case AARCH64_CMODEL_TINY_PIC: > diff --git a/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c > b/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c > index > d7e46b059e41f2672b3a1da5506fa8944e752e01..d49ff4dbe5786ef6d343d2b90052c09676dd7fe5 > 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[0x00200000]; > > 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..75c87c12f08004c153efc5192e5cfab566c089db > 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[0x200000000ULL]; > > int > -foo() > +main () > { > - return fixed_regs[0x100000000ULL]; > + return fixed_regs[0xfffff000ULL]; > } > > /* { dg-final { scan-assembler-not "adrp\tx\[0-9\]+, fixed_regs\\\+" } } > */