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

Reply via email to