The mips64vr-elf target will fail building newlib, particularly the mips16 newlib as we emit bogus assembly code.

In particular the compiler will emit something like

lwu $2,0($sp)

That's invalid in mips16 mode AFAICT.

That's emitted by the extendsidi pattern. It's a case where the operand predicates are looser that the constraints. The code we get out of reload is fine, but hard register propagation substitutes sp for a (valid mips16) hard register that as the same value. Since hard register propagation tests predicates, not constraints, the substitution is successful and the bogus code is generated.

Sadly, we don't have a good predicate to use for the source operand of an extendsidi pattern. In general sp+offset is a valid memory address, but not for lwu.

I briefly pondered disabling the pattern for mips16, but that seems somewhat anti-performant. So I looked at alternatives.

I poked a bit at adding an appropriate operand predicate, but it just gets ugly as to do it right. I'd want to use some of the GO_IF_LEGITIMATE_ADDRESS machinery to decompose the address. But everything is static. Exposing it would be possible I suppose.

I could also have passed in a flag to the GO_IF_LEGITIMATE_ADDRESS machinery to indicating we're handling lwu, but that seemed hacky.

Instead I added additional tests to the pattern's condition to verify that if TARGET_MIPS16 was active, the input operand was not a MEM where sp appears in the address. That's fairly surgical so we're not going to adversely affect code generation and doesn't require hacking up the GO_IF_LEGITIMATE_ADDRESS machinery.

That allows mips64vr-elf to build newlib & libgcc. It was certainly a regression as we've been able to build mips16 newlib multilibs in the past.

Installing on the trunk.

Jeff


ps. bz74563 (P2 regression) is an unrelated mips16 issue introduced a couple years ago that probably makes classic mips16 unusable right now. I may take a stab at fixing that too since I have a reasonable idea what's happening.
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 33b094e..788f029 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2017-04-13  Jeff Law  <l...@redhat.com>
+
+       * config/mips.mips.md (zero_extendsidi2): Do not allow SP to appear
+       in operands[1] if it is a MEM and TARGET_MIPS16 is active.
+       (zero_extendsidi2_dext): Likewise.
+
 2017-04-13  Jakub Jelinek  <ja...@redhat.com>
 
        PR sanitizer/80403
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 7acf00d..dd5e1e7 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -3493,7 +3493,10 @@
 (define_insn_and_split "*zero_extendsidi2"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
-  "TARGET_64BIT && !ISA_HAS_EXT_INS"
+  "TARGET_64BIT && !ISA_HAS_EXT_INS
+   && !(TARGET_MIPS16
+        && MEM_P (operands[1])
+        && reg_mentioned_p (stack_pointer_rtx, operands[1]))"
   "@
    #
    lwu\t%0,%1"
@@ -3509,7 +3512,10 @@
 (define_insn "*zero_extendsidi2_dext"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
-  "TARGET_64BIT && ISA_HAS_EXT_INS"
+  "TARGET_64BIT && ISA_HAS_EXT_INS
+   && !(TARGET_MIPS16
+        && MEM_P (operands[1])
+        && reg_mentioned_p (stack_pointer_rtx, operands[1]))"
   "@
    dext\t%0,%1,0,32
    lwu\t%0,%1"

Reply via email to