On Fri, Sep 06, 2013 at 02:18:49PM -0400, David Edelsohn wrote:
> On Fri, Sep 6, 2013 at 3:13 AM, Alan Modra <[email protected]> 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