https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79058

--- Comment #22 from Dominik Vogt <vogt at linux dot vnet.ibm.com> ---
That looks like a similar problem.  I'm lacking some knowledge about how
register pairs are allocated for paradoxical subregs on bigendian systems
though.  Deducing from the code quoted above and from what register allocation
generates; is this correct?

On a 32 bit, bigendian system, the register pair for r<n>:SI is

* r<n>/r<n+1> for input operands (OP_IN)
* r<n-1>/r<n> for output operands (OP_OUT or OP_INOUT)

Are even/odd and odd/even pairs both valid?

--

Assuming this is correct... 

For the pseudoregs in

> (insn 11 8 15 2 (set (reg:DI 118)
>         (and:DI (subreg:DI (reg:SI 116) 0)
>             (const_int 1 [0x1]))) "pr79058b.c":13 79 {*anddi3_insn}

Ira chooses r2 for both, r116 and r118:

> Disposition:
>     ... 1:r116 l0     2    0:r118 l0     2

Lra then expands the paradoxical subreg in r116, using r122:

>        Choosing alt 5 in insn 11:  (0) &r  (1) r  (2) De {*anddi3_insn}
>      Creating newreg=122 from oldreg=118, assigning class GENERAL_REGS to r122
>   11: r122:DI=r116:SI#0&0x1
>      REG_DEAD r116:SI
>     Inserting insn reload after:
>    21: r118:DI=r122:DI

and reloads r122 to r0:

>         Assigning to 122 (cl=GENERAL_REGS, orig=118, freq=2000, tfirst=122, 
> tfreq=2000)...
>            Assign 0 to reload r122 (freq=2000)

As r116:SI (r2:SI) maps to r116-1:DI (r1:DI) this results in

> (insn 11 8 21 2 (set (reg:DI 0 r0 [118])
>         (and:DI (reg:DI 1 r1 [orig:116+-4 ] [116])
>             (const_int 1 [0x1]))) "pr79058b.c":13 79 {*anddi3_insn}

With the register pair r0/r1 [118] overlapping the pair r1/r2 [116].  Because
of the earlyclobber in the pattern, this test "fails" and alternative 5 does
not match:

  if ((MEM_P (recog_data.operand[opno]) 
       || recog_data.operand_type[opno] != OP_OUT) 
      && opno != eopno 
      /* Ignore things like match_operator operands.  */ 
      && *recog_data.constraints[opno] != 0 
      && ! (matching_operands[opno] == eopno 
            && operands_match_p (recog_data.operand[opno], 
                                 recog_data.operand[eopno])) 
      && ! safe_from_earlyclobber (recog_data.operand[opno], 
                                   recog_data.operand[eopno])) 
    lose = 1; 

(safe_from_earlyclobber correctly returns false because of the overlapping
register pairs).

Now, where should this conflict have been noticed?  This may again be a case
where the code assumes that the register pair is r2/r3, but on bigendian it is
r1/r2, but what is the place to look for this code?

Reply via email to