On Tue, Nov 25, 2014 at 09:13:10AM +0100, Uros Bizjak wrote:
> On Tue, Nov 25, 2014 at 8:40 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
> > On Tue, Nov 25, 2014 at 12:25 AM, Jakub Jelinek <ja...@redhat.com> wrote:
> >
> >> The fallback delegitimization I've added as last option mainly for
> >> debug info purposes, when we don't know if the base is a PIC register
> >> or say a PIC register plus some addend, unfortunately in some tests
> >> broke find_base_term, which for PLUS looks only at the first operand
> >> and recursion on it finds a base term, it returns it immediately.
> >> So, it found base term of _GLOBAL_OFFSET_TABLE_, when the right base
> >> term is actually in the second operand.
> >>
> >> This patch fixes it by swapping the operands, debug info doesn't care about
> >> the order, it won't match in any instruction anyway, but helps alias.c.
> >>
> >> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> >>
> >> 2014-11-24  Jakub Jelinek  <ja...@redhat.com>
> >>
> >>         PR lto/64025
> >>         * config/i386/i386.c (ix86_delegitimize_address): Ensure result
> >>         comes before (addend - _GLOBAL_OFFSET_TABLE_) term.
> >
> > Can you also swap operands of (%ecx - %ebx) + foo? There is no point
> > digging into RTX involving registers only when we know that we are
> > looking for foo. This will also be consistent with the code you
> > patched below.
> 
> Something like attached prototype patch.

Actually, thinking about it more, at least according to
commutative_operand_precedence the canonical order is
what we used to return (i.e. (something - _G_O_T_) + (symbol_ref)
or
(something - _G_O_T_) + (const (symbol_ref +- const))
So perhaps better fix is to follow find_base_value, which does something
like:
        /* Guess which operand is the base address:
           If either operand is a symbol, then it is the base.  If
           either operand is a CONST_INT, then the other is the base.  */
        if (CONST_INT_P (src_1) || CONSTANT_P (src_0))
          return find_base_value (src_0);
        else if (CONST_INT_P (src_0) || CONSTANT_P (src_1))
          return find_base_value (src_1);
and do something similar in find_base_term too.  I.e. perhaps even with
higher precedence over REG_P with REG_POINTER (or lower, in these cases
it doesn't really matter, neither argument is REG_P), choose first
operand that is CONSTANT_P and not CONST_INT_P.

        Jakub

Reply via email to