public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* hard_regno_nregs == 0 ?
@ 2008-01-08 20:13 DJ Delorie
  2008-01-09 16:43 ` Ian Lance Taylor
  2008-01-09 19:27 ` Jim Wilson
  0 siblings, 2 replies; 13+ messages in thread
From: DJ Delorie @ 2008-01-08 20:13 UTC (permalink / raw)
  To: gcc


In rtlanal.c we have these lines:

  nregs_ymode = hard_regno_nregs[xregno][ymode];
  ...
      && (GET_MODE_SIZE (ymode) % nregs_ymode) == 0)

The m32c cc1 crashes here because xregno is 1 and ymode is QI, and
register 1 cannot hold a QI value (there are no QImode ops that take
that register), so hard_regno_nregs[1][QI] is zero, which causes a
SIGFPE.

Which assumption is wrong?  That hard_regno_nregs can be zero (m32c),
or that hard_regno_nregs will never be zero (rtlanal)?

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

* Re: hard_regno_nregs == 0 ?
  2008-01-08 20:13 hard_regno_nregs == 0 ? DJ Delorie
@ 2008-01-09 16:43 ` Ian Lance Taylor
  2008-01-09 16:47   ` DJ Delorie
  2008-01-09 19:27 ` Jim Wilson
  1 sibling, 1 reply; 13+ messages in thread
From: Ian Lance Taylor @ 2008-01-09 16:43 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc

DJ Delorie <dj@redhat.com> writes:

> In rtlanal.c we have these lines:
> 
>   nregs_ymode = hard_regno_nregs[xregno][ymode];
>   ...
>       && (GET_MODE_SIZE (ymode) % nregs_ymode) == 0)
> 
> The m32c cc1 crashes here because xregno is 1 and ymode is QI, and
> register 1 cannot hold a QI value (there are no QImode ops that take
> that register), so hard_regno_nregs[1][QI] is zero, which causes a
> SIGFPE.
> 
> Which assumption is wrong?  That hard_regno_nregs can be zero (m32c),
> or that hard_regno_nregs will never be zero (rtlanal)?

I would first ask why subreg_get_info is being called with ymode ==
QImode for a hard register which can not hold QImode.  That implies
that there is a QImode value in the register, which you say is
invalid.

Ian

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

* Re: hard_regno_nregs == 0 ?
  2008-01-09 16:43 ` Ian Lance Taylor
@ 2008-01-09 16:47   ` DJ Delorie
  2008-01-09 16:56     ` Ian Lance Taylor
  2008-01-09 20:18     ` Jim Wilson
  0 siblings, 2 replies; 13+ messages in thread
From: DJ Delorie @ 2008-01-09 16:47 UTC (permalink / raw)
  To: iant; +Cc: gcc


> I would first ask why subreg_get_info is being called with ymode ==
> QImode for a hard register which can not hold QImode.  That implies
> that there is a QImode value in the register, which you say is
> invalid.

Are there any ports besides m32c that have registers which can hold HI
(or SI I suppose) but not QI values?

What I've done as a workaround is check for the zero and fail nicely:

Index: rtlanal.c
===================================================================
--- rtlanal.c	(revision 131405)
+++ rtlanal.c	(working copy)
@@ -3135,12 +3135,20 @@ subreg_get_info (unsigned int xregno, en
       else
 	info->offset = 0;
       info->nregs = nregs_ymode;
       return;
     }
 
+  if (nregs_ymode == 0)
+    {
+      info->representable_p = false;
+      info->nregs = 1;
+      info->offset = offset;
+      return false;
+    }
+
   /* If registers store different numbers of bits in the different
      modes, we cannot generally form this subreg.  */
   if (!HARD_REGNO_NREGS_HAS_PADDING (xregno, xmode)
       && !HARD_REGNO_NREGS_HAS_PADDING (xregno, ymode)
       && (GET_MODE_SIZE (xmode) % nregs_xmode) == 0
       && (GET_MODE_SIZE (ymode) % nregs_ymode) == 0)

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

* Re: hard_regno_nregs == 0 ?
  2008-01-09 16:47   ` DJ Delorie
@ 2008-01-09 16:56     ` Ian Lance Taylor
  2008-01-09 20:18     ` Jim Wilson
  1 sibling, 0 replies; 13+ messages in thread
From: Ian Lance Taylor @ 2008-01-09 16:56 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc

DJ Delorie <dj@redhat.com> writes:

> > I would first ask why subreg_get_info is being called with ymode ==
> > QImode for a hard register which can not hold QImode.  That implies
> > that there is a QImode value in the register, which you say is
> > invalid.
> 
> Are there any ports besides m32c that have registers which can hold HI
> (or SI I suppose) but not QI values?

Good point.  I would normally say that they can hold QI values--after
all, they can--but use register constraints for any QI operations.
Treat movqi for such registers as movhi, or whatever.

Ian

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

* Re: hard_regno_nregs == 0 ?
  2008-01-08 20:13 hard_regno_nregs == 0 ? DJ Delorie
  2008-01-09 16:43 ` Ian Lance Taylor
@ 2008-01-09 19:27 ` Jim Wilson
  2008-01-09 20:39   ` DJ Delorie
  1 sibling, 1 reply; 13+ messages in thread
From: Jim Wilson @ 2008-01-09 19:27 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc

DJ Delorie wrote:
> Which assumption is wrong?  That hard_regno_nregs can be zero (m32c),
> or that hard_regno_nregs will never be zero (rtlanal)?

I would say the m32c port is wrong.  HARD_REGNO_MODE_OK indicates 
whether a register can hold a mode.  HARD_REGNO_NREGS indicates how many 
registers we need to hold a value.  This is a number that can be larger 
than 1 if the value is larger than one register, but it makes no sense 
for it to be zero, as no (non-void) value can ever be held in zero 
registers.  The number of registers needed is irrespective of whether 
the register can actually hold the value, as that is specified by 
HARD_REGNO_MODE_OK.  There are lots of places that use HARD_REGNO_NREGS 
in division/modulus operations.  It would be complicated to fix them all 
to handle a zero value.

However, as Ian mentioned, there does seem to be something else wrong 
here, as it seems odd that you have an invalid subreg being passed in here.
-- 
Jim Wilson, GNU Tools Support, http://www.specifix.com

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

* Re: hard_regno_nregs == 0 ?
  2008-01-09 16:47   ` DJ Delorie
  2008-01-09 16:56     ` Ian Lance Taylor
@ 2008-01-09 20:18     ` Jim Wilson
  1 sibling, 0 replies; 13+ messages in thread
From: Jim Wilson @ 2008-01-09 20:18 UTC (permalink / raw)
  To: DJ Delorie; +Cc: iant, gcc

DJ Delorie wrote:
> Are there any ports besides m32c that have registers which can hold HI
> (or SI I suppose) but not QI values?

IA-64 has branch registers that are only allowed to hold DImode values. 
  We use CANNOT_CHANGE_MODE_CLASS to enforce this.

On x86, the vector registers can hold SImode, but do not allow 
HImode/QImode loads, and again CANNOT_CHANGE_MODE_CLASS is used to 
enforce this.

I'm sure that there are other examples out there.
-- 
Jim Wilson, GNU Tools Support, http://www.specifix.com

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

* Re: hard_regno_nregs == 0 ?
  2008-01-09 19:27 ` Jim Wilson
@ 2008-01-09 20:39   ` DJ Delorie
  2008-01-09 21:48     ` Paul Brook
  2008-01-11  0:12     ` Jim Wilson
  0 siblings, 2 replies; 13+ messages in thread
From: DJ Delorie @ 2008-01-09 20:39 UTC (permalink / raw)
  To: wilson; +Cc: gcc


How about this change, then?  (I'm still testing the m32c change, too)

2008-01-09  DJ Delorie  <dj@redhat.com>

	* doc/tm.texi (HARD_REGNO_NREGS): Note that this macro must not
	return zero.

Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 131434)
+++ doc/tm.texi	(working copy)
@@ -2076,13 +2076,15 @@ This section discusses the macros that d
 (specifically, which machine modes) each register can hold, and how many
 consecutive registers are needed for a given mode.
 
 @defmac HARD_REGNO_NREGS (@var{regno}, @var{mode})
 A C expression for the number of consecutive hard registers, starting
 at register number @var{regno}, required to hold a value of mode
-@var{mode}.
+@var{mode}.  This macro must never return zero, even if a register
+cannot hold the requested mode - indicate that with HARD_REGNO_MODE_OK
+and/or CANNOT_CHANGE_MODE_CLASS instead.
 
 On a machine where all registers are exactly one word, a suitable
 definition of this macro is
 
 @smallexample
 #define HARD_REGNO_NREGS(REGNO, MODE)            \

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

* Re: hard_regno_nregs == 0 ?
  2008-01-09 20:39   ` DJ Delorie
@ 2008-01-09 21:48     ` Paul Brook
  2008-01-09 22:02       ` DJ Delorie
  2008-01-11  0:12     ` Jim Wilson
  1 sibling, 1 reply; 13+ messages in thread
From: Paul Brook @ 2008-01-09 21:48 UTC (permalink / raw)
  To: gcc; +Cc: DJ Delorie, wilson

>  @defmac HARD_REGNO_NREGS (@var{regno}, @var{mode})
>  A C expression for the number of consecutive hard registers, starting
>  at register number @var{regno}, required to hold a value of mode
> -@var{mode}.
> +@var{mode}.  This macro must never return zero, even if a register
> +cannot hold the requested mode - indicate that with HARD_REGNO_MODE_OK
> +and/or CANNOT_CHANGE_MODE_CLASS instead.

I find this somewhat unclear - It seems to imply that HARD_REGNO_NREGS may be 
called even when HARD_REGNO_MODE_OK returns false.

How about:

This macro must return a nonzero value for all combinations permitted by 
HARD_REGNO_MODE_OK and CANNOT_CHANGE_MODE_CLASS.

Paul

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

* Re: hard_regno_nregs == 0 ?
  2008-01-09 21:48     ` Paul Brook
@ 2008-01-09 22:02       ` DJ Delorie
  0 siblings, 0 replies; 13+ messages in thread
From: DJ Delorie @ 2008-01-09 22:02 UTC (permalink / raw)
  To: paul; +Cc: gcc, wilson


> I find this somewhat unclear - It seems to imply that HARD_REGNO_NREGS may be 
> called even when HARD_REGNO_MODE_OK returns false.

That's exactly the case that's happening for m32c, and for which the
new text is needed.

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

* Re: hard_regno_nregs == 0 ?
  2008-01-09 20:39   ` DJ Delorie
  2008-01-09 21:48     ` Paul Brook
@ 2008-01-11  0:12     ` Jim Wilson
  2008-01-11  0:16       ` DJ Delorie
  1 sibling, 1 reply; 13+ messages in thread
From: Jim Wilson @ 2008-01-11  0:12 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc

On Wed, 2008-01-09 at 15:38 -0500, DJ Delorie wrote:
> +@var{mode}.  This macro must never return zero, even if a register
> +cannot hold the requested mode - indicate that with HARD_REGNO_MODE_OK
> +and/or CANNOT_CHANGE_MODE_CLASS instead.

I think that HARD_REGNO_NREGS should not be returning zero, but I also
think it is a moot point, as we shouldn't be using it on invalid
subregs.  Hence I like Paul's wording better than yours, but it appears
not to be sufficient for your case, as your m32c is only fixing
HARD_REGNO_NREGS to not return zero.  It appears that the m32c port does
define both HARD_REGNO_MODE_OK and CANNOT_CHANGE_MODE_CLASS, so it isn't
clear what the problem is.  I suspect that there may be another problem
here.  Unfortunately, I don't have a testcase I can use to look at this
myself.  Maybe if we found and fixed this other problem, Paul's wording
would be correct again.
-- 
Jim Wilson, GNU Tools Support, http://www.specifix.com


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

* Re: hard_regno_nregs == 0 ?
  2008-01-11  0:12     ` Jim Wilson
@ 2008-01-11  0:16       ` DJ Delorie
  2008-01-12  0:48         ` Jim Wilson
  0 siblings, 1 reply; 13+ messages in thread
From: DJ Delorie @ 2008-01-11  0:16 UTC (permalink / raw)
  To: wilson; +Cc: gcc


IIRC, the bug happened building either libgcc or newlib.  If you want
to revert my latest patch in a local source tree and just try a build,
it's likely to show you an example ;-)

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

* Re: hard_regno_nregs == 0 ?
  2008-01-11  0:16       ` DJ Delorie
@ 2008-01-12  0:48         ` Jim Wilson
  2008-01-21 22:41           ` DJ Delorie
  0 siblings, 1 reply; 13+ messages in thread
From: Jim Wilson @ 2008-01-12  0:48 UTC (permalink / raw)
  To: DJ Delorie; +Cc: gcc

On Thu, 2008-01-10 at 19:16 -0500, DJ Delorie wrote:
> IIRC, the bug happened building either libgcc or newlib.  If you want
> to revert my latest patch in a local source tree and just try a build,
> it's likely to show you an example ;-)

It was unwind-dw2.c in the m32cm libgcc multilib.

The problem lies with the var-tracking pass.  It sees a QImode variable
being held in an HImode hard-reg, and decides to track only the low
QImode part.  This happens in track_loc_p, when it decides to use
DECL_MODE instead of the hard reg mode.  We then have to create RTL to
represent the part that we are tracking, which means we have to create
an invalid QImode lowpart of a hard reg that can't hold QImode values.
Since we will only use this for emitting debug info this seems perfectly
harmless.  Unfortunately, this does mean that HARD_REGNO_NREGS must work
correctly for invalid register modes.  We need that info in order to
construct the lowpart/subreg.  Nowhere does var-tracking check to see if
it is creating a valid register references, nor do I think this is
necessary.

Hence, I now believe that your suggested doc change is correct, and is
OK to check in to mainline.
-- 
Jim Wilson, GNU Tools Support, http://www.specifix.com


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

* Re: hard_regno_nregs == 0 ?
  2008-01-12  0:48         ` Jim Wilson
@ 2008-01-21 22:41           ` DJ Delorie
  0 siblings, 0 replies; 13+ messages in thread
From: DJ Delorie @ 2008-01-21 22:41 UTC (permalink / raw)
  To: wilson; +Cc: gcc


> Hence, I now believe that your suggested doc change is correct, and is
> OK to check in to mainline.

Committed.  Thanks!

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 131702)
+++ ChangeLog	(working copy)
@@ -1,6 +1,11 @@
+2008-01-21  DJ Delorie  <dj@redhat.com>
+
+	* doc/tm.texi (HARD_REGNO_NREGS): Note that this macro must not
+	return zero.
+
 2008-01-21  Richard Guenther  <rguenther@suse.de>
 
 	PR middle-end/34856
 	* tree-cfg.c (verify_expr): Allow all invariant expressions
 	instead of just constant class ones as reference argument.
 	* tree-ssa-loop-im.c (for_each_index): Handle CONSTRUCTOR
Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 131702)
+++ doc/tm.texi	(working copy)
@@ -2076,13 +2076,15 @@ This section discusses the macros that d
 (specifically, which machine modes) each register can hold, and how many
 consecutive registers are needed for a given mode.
 
 @defmac HARD_REGNO_NREGS (@var{regno}, @var{mode})
 A C expression for the number of consecutive hard registers, starting
 at register number @var{regno}, required to hold a value of mode
-@var{mode}.
+@var{mode}.  This macro must never return zero, even if a register
+cannot hold the requested mode - indicate that with HARD_REGNO_MODE_OK
+and/or CANNOT_CHANGE_MODE_CLASS instead.
 
 On a machine where all registers are exactly one word, a suitable
 definition of this macro is
 
 @smallexample
 #define HARD_REGNO_NREGS(REGNO, MODE)            \

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

end of thread, other threads:[~2008-01-21 22:21 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-08 20:13 hard_regno_nregs == 0 ? DJ Delorie
2008-01-09 16:43 ` Ian Lance Taylor
2008-01-09 16:47   ` DJ Delorie
2008-01-09 16:56     ` Ian Lance Taylor
2008-01-09 20:18     ` Jim Wilson
2008-01-09 19:27 ` Jim Wilson
2008-01-09 20:39   ` DJ Delorie
2008-01-09 21:48     ` Paul Brook
2008-01-09 22:02       ` DJ Delorie
2008-01-11  0:12     ` Jim Wilson
2008-01-11  0:16       ` DJ Delorie
2008-01-12  0:48         ` Jim Wilson
2008-01-21 22:41           ` DJ Delorie

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).