[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