On Fri, Sep 06, 2013 at 02:18:49PM -0400, David Edelsohn wrote: > On Fri, Sep 6, 2013 at 3:13 AM, Alan Modra <amo...@gmail.com> wrote: > > The following testcase taken from the linux kernel is miscompiled on > > powerpc64-linux. > > > > /* -m64 -mcmodel=medium -O -S -fno-section-anchors */ > > static int x; > > > > unsigned long > > foo (void) > > { > > return ((unsigned long) &x) - 0xc000000000000000; > > } > > > > generates > > addis 3,2,x+4611686018427387904@toc@ha > > addi 3,3,x+4611686018427387904@toc@l > > blr > > > > losing the top 32 bits of the offset. Sadly, the assembler and linker > > do not complain, which is a hole in the ABI. (@ha and _HA relocs as > > per the ABI won't complain about overflow since they might be used in > > a @highesta, @highera sequence loading a 64-bit value.) > > > > This patch stops combine merging large offsets into a symbol addend > > by copying code from reg_or_add_cint_operand to a new predicate, > > add_cint_operand, and using that to restrict the range of offsets. > > Bootstrapped and regression tested powerpc64-linux. OK to apply? > > > > * config/rs6000/predicates.md (add_cint_operand): New. > > * config/rs6000/rs6000.md (largetoc_high_plus): Restrict offset > > using add_cint_operand. > > (largetoc_high_plus_aix): Likewise. > > This patch should include a testcase. > > But what user feedback are you expecting if the offset is too large, > such as your example? In my test with the patch, it produces an > unrecognizable insn error, which seems less than friendly.
The testcase gives me .L.foo: lis 9,0x4000 sldi 9,9,32 addis 3,2,x@toc@ha addi 3,3,x@toc@l add 3,3,9 blr How did you manage to get an unrecognizable insn? I can't see how we generate the pattern except in combine. -- Alan Modra Australia Development Lab, IBM