public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix newlib build failure for mips16
@ 2017-04-14  5:14 Jeff Law
  2017-04-14 11:43 ` Richard Sandiford
  0 siblings, 1 reply; 7+ messages in thread
From: Jeff Law @ 2017-04-14  5:14 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2049 bytes --]



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.

[-- Attachment #2: P --]
[-- Type: text/plain, Size: 1416 bytes --]

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"

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix newlib build failure for mips16
  2017-04-14  5:14 [PATCH] Fix newlib build failure for mips16 Jeff Law
@ 2017-04-14 11:43 ` Richard Sandiford
  2017-04-14 16:25   ` Jeff Law
  0 siblings, 1 reply; 7+ messages in thread
From: Richard Sandiford @ 2017-04-14 11:43 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

Jeff Law <law@redhat.com> writes:
> 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.

Isn't that the bug though?  Post-reload passes must test the constraints
as well as the predicates, to make sure that the change aligns with
one of the available alternatives.

Adding code to do that to individual MIPS patterns feels like a hack to me.
The pass should be doing it itself.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix newlib build failure for mips16
  2017-04-14 11:43 ` Richard Sandiford
@ 2017-04-14 16:25   ` Jeff Law
  2017-04-14 17:01     ` Richard Sandiford
  0 siblings, 1 reply; 7+ messages in thread
From: Jeff Law @ 2017-04-14 16:25 UTC (permalink / raw)
  To: gcc-patches, rdsandiford

On 04/14/2017 05:22 AM, Richard Sandiford wrote:
> Jeff Law <law@redhat.com> writes:
>> 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.
>
> Isn't that the bug though?  Post-reload passes must test the constraints
> as well as the predicates, to make sure that the change aligns with
> one of the available alternatives.
I thought that as well and was quite surprised to see regcprop not honor 
that.

regcprop uses the validate_change interface, which normally checks 
contraints -- except for MEMs which is just checks for validity via 
memory_address_addr_space_p.  Thus inside a MEM it'll allow any change 
that is recognized as valid according to the legitimate_address hooks.

I would claim that is fundamentally broken, but trying to change that at 
this stage is, IMHO, unwise.  I think we should seriously consider doing 
something different for stage1.  For example, after validating the MEM 
using the legitimate address hooks, call insn_invalid_p as well to 
verify constraints.


>
> Adding code to do that to individual MIPS patterns feels like a hack to me.
> The pass should be doing it itself.
Agreed.  It's a hack.  But it was the best I could see to do at this stage.

jeff

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix newlib build failure for mips16
  2017-04-14 16:25   ` Jeff Law
@ 2017-04-14 17:01     ` Richard Sandiford
  2017-04-14 17:09       ` Jeff Law
  2017-04-14 21:17       ` Jeff Law
  0 siblings, 2 replies; 7+ messages in thread
From: Richard Sandiford @ 2017-04-14 17:01 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

Jeff Law <law@redhat.com> writes:
> On 04/14/2017 05:22 AM, Richard Sandiford wrote:
>> Jeff Law <law@redhat.com> writes:
>>> 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.
>>
>> Isn't that the bug though?  Post-reload passes must test the constraints
>> as well as the predicates, to make sure that the change aligns with
>> one of the available alternatives.
> I thought that as well and was quite surprised to see regcprop not honor 
> that.
>
> regcprop uses the validate_change interface, which normally checks 
> contraints -- except for MEMs which is just checks for validity via 
> memory_address_addr_space_p.  Thus inside a MEM it'll allow any change 
> that is recognized as valid according to the legitimate_address hooks.
>
> I would claim that is fundamentally broken, but trying to change that at 
> this stage is, IMHO, unwise.  I think we should seriously consider doing 
> something different for stage1.  For example, after validating the MEM 
> using the legitimate address hooks, call insn_invalid_p as well to 
> verify constraints.

I think it only does that if the "containing object" that you're
validating is a MEM.  If the object you're validating is an insn
(which it always is for regcprop) then normal constrain_operands
does happen.

>> Adding code to do that to individual MIPS patterns feels like a hack to me.
>> The pass should be doing it itself.
> Agreed.  It's a hack.  But it was the best I could see to do at this stage.

Been looking at it a bit more, and I think the problem is that we're
somehow ending up with a second stack pointer rtx, distinct from
stack_pointer_rtx.  And then I remembered that this had been discussed
before, see the tail end of:

   https://gcc.gnu.org/ml/gcc-patches/2016-01/msg02362.html

I'd be happier with the mips_stack_address_p change described there,
although it still seems like a hack.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix newlib build failure for mips16
  2017-04-14 17:01     ` Richard Sandiford
@ 2017-04-14 17:09       ` Jeff Law
  2017-04-14 17:30         ` Jeff Law
  2017-04-14 21:17       ` Jeff Law
  1 sibling, 1 reply; 7+ messages in thread
From: Jeff Law @ 2017-04-14 17:09 UTC (permalink / raw)
  To: gcc-patches, rdsandiford

On 04/14/2017 10:24 AM, Richard Sandiford wrote:
>
> I think it only does that if the "containing object" that you're
> validating is a MEM.  If the object you're validating is an insn
> (which it always is for regcprop) then normal constrain_operands
> does happen.
Hmm, you've of course right!


>
>>> Adding code to do that to individual MIPS patterns feels like a hack to me.
>>> The pass should be doing it itself.
>> Agreed.  It's a hack.  But it was the best I could see to do at this stage.
>
> Been looking at it a bit more, and I think the problem is that we're
> somehow ending up with a second stack pointer rtx, distinct from
> stack_pointer_rtx.  And then I remembered that this had been discussed
> before, see the tail end of:
>
>    https://gcc.gnu.org/ml/gcc-patches/2016-01/msg02362.html
>
> I'd be happier with the mips_stack_address_p change described there,
> although it still seems like a hack.
Let me dig a little further.  Two stack pointers just sounds 
fundamentally wrong.

jeff

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix newlib build failure for mips16
  2017-04-14 17:09       ` Jeff Law
@ 2017-04-14 17:30         ` Jeff Law
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff Law @ 2017-04-14 17:30 UTC (permalink / raw)
  To: gcc-patches, rdsandiford

On 04/14/2017 11:01 AM, Jeff Law wrote:
> On 04/14/2017 10:24 AM, Richard Sandiford wrote:
>>
>> I think it only does that if the "containing object" that you're
>> validating is a MEM.  If the object you're validating is an insn
>> (which it always is for regcprop) then normal constrain_operands
>> does happen.
> Hmm, you've of course right!
>
>
>>
>>>> Adding code to do that to individual MIPS patterns feels like a hack
>>>> to me.
>>>> The pass should be doing it itself.
>>> Agreed.  It's a hack.  But it was the best I could see to do at this
>>> stage.
>>
>> Been looking at it a bit more, and I think the problem is that we're
>> somehow ending up with a second stack pointer rtx, distinct from
>> stack_pointer_rtx.  And then I remembered that this had been discussed
>> before, see the tail end of:
>>
>>    https://gcc.gnu.org/ml/gcc-patches/2016-01/msg02362.html
>>
>> I'd be happier with the mips_stack_address_p change described there,
>> although it still seems like a hack.
> Let me dig a little further.  Two stack pointers just sounds
> fundamentally wrong.
See maybe_mode_change and cry.

jeff

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix newlib build failure for mips16
  2017-04-14 17:01     ` Richard Sandiford
  2017-04-14 17:09       ` Jeff Law
@ 2017-04-14 21:17       ` Jeff Law
  1 sibling, 0 replies; 7+ messages in thread
From: Jeff Law @ 2017-04-14 21:17 UTC (permalink / raw)
  To: gcc-patches, rdsandiford

[-- Attachment #1: Type: text/plain, Size: 2748 bytes --]

On 04/14/2017 10:24 AM, Richard Sandiford wrote:
> Jeff Law <law@redhat.com> writes:
>> On 04/14/2017 05:22 AM, Richard Sandiford wrote:
>>> Jeff Law <law@redhat.com> writes:
>>>> 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.
>>>
>>> Isn't that the bug though?  Post-reload passes must test the constraints
>>> as well as the predicates, to make sure that the change aligns with
>>> one of the available alternatives.
>> I thought that as well and was quite surprised to see regcprop not honor
>> that.
>>
>> regcprop uses the validate_change interface, which normally checks
>> contraints -- except for MEMs which is just checks for validity via
>> memory_address_addr_space_p.  Thus inside a MEM it'll allow any change
>> that is recognized as valid according to the legitimate_address hooks.
>>
>> I would claim that is fundamentally broken, but trying to change that at
>> this stage is, IMHO, unwise.  I think we should seriously consider doing
>> something different for stage1.  For example, after validating the MEM
>> using the legitimate address hooks, call insn_invalid_p as well to
>> verify constraints.
>
> I think it only does that if the "containing object" that you're
> validating is a MEM.  If the object you're validating is an insn
> (which it always is for regcprop) then normal constrain_operands
> does happen.
>
>>> Adding code to do that to individual MIPS patterns feels like a hack to me.
>>> The pass should be doing it itself.
>> Agreed.  It's a hack.  But it was the best I could see to do at this stage.
>
> Been looking at it a bit more, and I think the problem is that we're
> somehow ending up with a second stack pointer rtx, distinct from
> stack_pointer_rtx.  And then I remembered that this had been discussed
> before, see the tail end of:
>
>    https://gcc.gnu.org/ml/gcc-patches/2016-01/msg02362.html
>
> I'd be happier with the mips_stack_address_p change described there,
> although it still seems like a hack.
Here's what I'm going to spin in my testers over the weekend.  It 
reverts my mips.md change and instead rejects making a copy of the stack 
pointer.

Jeff


[-- Attachment #2: P --]
[-- Type: text/plain, Size: 1695 bytes --]

diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index dd5e1e7..7acf00d 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -3493,10 +3493,7 @@
 (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_MIPS16
-        && MEM_P (operands[1])
-        && reg_mentioned_p (stack_pointer_rtx, operands[1]))"
+  "TARGET_64BIT && !ISA_HAS_EXT_INS"
   "@
    #
    lwu\t%0,%1"
@@ -3512,10 +3509,7 @@
 (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_MIPS16
-        && MEM_P (operands[1])
-        && reg_mentioned_p (stack_pointer_rtx, operands[1]))"
+  "TARGET_64BIT && ISA_HAS_EXT_INS"
   "@
    dext\t%0,%1,0,32
    lwu\t%0,%1"
diff --git a/gcc/regcprop.c b/gcc/regcprop.c
index ddc6252..367d85a 100644
--- a/gcc/regcprop.c
+++ b/gcc/regcprop.c
@@ -396,6 +396,13 @@ maybe_mode_change (machine_mode orig_mode, machine_mode copy_mode,
       && GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (new_mode))
     return NULL_RTX;
 
+  /* Avoid creating multiple copies of the stack pointer.  Some ports
+     assume there is one and only one stack pointer.
+
+     It's unclear if we need to do the same for other special registers.  */
+  if (regno == STACK_POINTER_REGNUM)
+    return NULL_RTX;
+
   if (orig_mode == new_mode)
     return gen_raw_REG (new_mode, regno);
   else if (mode_change_ok (orig_mode, new_mode, regno))

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-04-14 17:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-14  5:14 [PATCH] Fix newlib build failure for mips16 Jeff Law
2017-04-14 11:43 ` Richard Sandiford
2017-04-14 16:25   ` Jeff Law
2017-04-14 17:01     ` Richard Sandiford
2017-04-14 17:09       ` Jeff Law
2017-04-14 17:30         ` Jeff Law
2017-04-14 21:17       ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).