[PATCH] Fix newlib build failure for mips16

Jeff Law law@redhat.com
Fri Apr 14 05:14:00 GMT 2017



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.
-------------- next part --------------
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  <law@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  <jakub@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"


More information about the Gcc-patches mailing list