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; + } + return and_load_operand (op2, mode); + } + else + return and_reg_operand (op2, mode); } /* The canonical form of a mask-low-and-shift-left operation is 2016-01-26 Steve Ellcey <sell...@imgtec.com> PR target/68400 * gcc.target/mips/mips.exp (mips_option_groups): Add stack-protector. * gcc.target/mips/pr68400.c: New test. diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index f191331..ff9c99a 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -257,6 +257,7 @@ set mips_option_groups { lsa "(|!)HAS_LSA" section_start "-Wl,--section-start=.*" frame-header "-mframe-header-opt|-mno-frame-header-opt" + stack-protector "-fstack-protector" } for { set option 0 } { $option < 32 } { incr option } { diff --git a/gcc/testsuite/gcc.target/mips/pr68400.c b/gcc/testsuite/gcc.target/mips/pr68400.c index e69de29..1099568 100644 --- a/gcc/testsuite/gcc.target/mips/pr68400.c +++ b/gcc/testsuite/gcc.target/mips/pr68400.c @@ -0,0 +1,28 @@ +/* PR target/pr68400 + This was triggering an ICE in change_address_1 when compiled with -Os. */ + +/* { dg-do compile } */ +/* { dg-options "-fstack-protector -mips16" } */ + +typedef struct s { + unsigned long long d; + long long t; +} p; + +int sh(int x, unsigned char *buf) +{ + p *uhdr = (p *)buf; + unsigned int i = 0; + uhdr->d = ((uhdr->d & 0xff00000000000000LL) >> 56) + | ((uhdr->d & 0x0000ff0000000000LL) >> 24) + | ((uhdr->d & 0x00000000ff000000LL) << 8) + | ((uhdr->d & 0x00000000000000ffLL) << 56); + uhdr->t = ((uhdr->t & 0xff00000000000000LL) >> 56) + | ((uhdr->t & 0x0000ff0000000000LL) >> 24) + | ((uhdr->t & 0x000000ff00000000LL) >> 8) + | ((uhdr->t & 0x00000000ff000000LL) << 8) + | ((uhdr->t & 0x000000000000ff00LL) << 40) + | ((uhdr->t & 0x00000000000000ffLL) << 56); + i += 4; + if (x < i) return 0; else return 1; +}