Richard Sandiford <rdsandif...@googlemail.com> writes: > "Steve Ellcey " <sell...@imgtec.com> writes: > > Here is a patch for PR6400. The problem is that and_operands_ok was > > checking > > one operand to see if it was a memory_operand but MIPS16 addressing is more > > restrictive than what the general memory_operand allows. The fix was to > > call mips_classify_address if TARGET_MIPS16 is set because it will do a > > more complete mips16 addressing check and reject operands that do not meet > > the more restrictive requirements. > > > > I ran the GCC testsuite with no regressions and have included a test case as > > part of this patch. > > > > OK to checkin? > > > > Steve Ellcey > > sell...@imgtec.com > > > > > > 2016-01-26 Steve Ellcey <sell...@imgtec.com> > > > > PR target/68400 > > * config/mips/mips.c (and_operands_ok): Add MIPS16 check. > > > > > > > > diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c > > index dd54d6a..adeafa3 100644 > > --- a/gcc/config/mips/mips.c > > +++ b/gcc/config/mips/mips.c > > @@ -8006,9 +8006,18 @@ mask_low_and_shift_p (machine_mode mode, rtx mask, > > rtx shift, int > maxlen) > > bool > > and_operands_ok (machine_mode mode, rtx op1, rtx op2) > > { > > - return (memory_operand (op1, mode) > > - ? and_load_operand (op2, mode) > > - : and_reg_operand (op2, mode)); > > + > > + if (memory_operand (op1, mode)) > > + { > > + if (TARGET_MIPS16) { > > + struct mips_address_info addr; > > + if (!mips_classify_address (&addr, op1, mode, false)) > > + return false; > > + } > > Nit: brace formatting. > > It looks like the patch only works by accident. The code above > is passing the MEM, rather than the address inside the MEM, to > mips_classify_address. Since (mem (mem ...)) is never valid on MIPS, > the effect is to disable the memory alternatives of *and<mode>3_mips16 > unconditionally. > > The addresses that occur in the testcase are valid as far as > mips_classify_address is concerned. FWIW, there shouldn't be any > difference between the addresses that memory_operand accepts and the > addresses that mips_classify_address accepts. > > In theory, the "W" constraints in *and<mode>3_mips16 are supposed to > tell the target-independent code that this instruction cannot handle > constant addresses or stack-based addresses. That seems to be working > correctly during RA for the testcase. The problem comes in regcprop, > which ends up creating a second stack pointer rtx distinct from > stack_pointer_rtx: > > (reg/f:SI 29 $sp [375]) > > (Note the ORIGINAL_REGNO of 375.) This then defeats the test in > mips_stack_address_p: > > bool > mips_stack_address_p (rtx x, machine_mode mode) > { > struct mips_address_info addr; > > return (mips_classify_address (&addr, x, mode, false) > && addr.type == ADDRESS_REG > && addr.reg == stack_pointer_rtx); > } > > Change the == to rtx_equal_p and the test passes. I don't think that's > the correct fix though -- the fix is to stop a second stack pointer rtx > from being created.
Agreed, though I'm inclined to say do both. We actually hit this same issue while testing some 4.9.2 based tools recently but I hadn't got confirmation from Andrew (cc'd) whether it was definitely the same issue. Andrew fixed this by updating all tests against stack_pointer_rtx to compare register numbers instead (but rtx_equal_p is better still). I think it is worthwhile looking in more detail why a new stack pointer rtx appears. Andrew did look briefly at the time but I don't recall his conclusions... Matthew