public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Bad mode-change inside subreg: DImode to SImode
@ 2004-03-13 20:10 Julian Brown
  2004-03-15 16:30 ` Julian Brown
  0 siblings, 1 reply; 2+ messages in thread
From: Julian Brown @ 2004-03-13 20:10 UTC (permalink / raw)
  To: gcc

Hi,

I am working on a port of GCC to a custom architecture, and I have
hit a problem recently (possibly since starting working against newer
versions of GCC) which I am having particular difficulty in solving. I
am working against the gcc-3_4-branch, but the same thing happens with
other recent branches.

The following code refuses to compile:

--
typedef struct {
  long long rem;
  long long quot;
} lldiv_t;

lldiv_t divlong (long long numer, long long denom)
{
  lldiv_t retval;

  if (numer >= 0) {
    retval.quot++;
  }
  return (retval);
}
--

giving the error:

divbug.c: In function `divlong':
divbug.c:14: internal compiler error: in simplify_subreg, at
simplify-rtx.c:3236

I have tracked this down for starters to the cse pass: beforehand, the
offending rtx looks like (from divbug.c.04.jump):

(insn 12 6 13 0 (set (reg:SI 137)
        (lt:SI (subreg:SI (reg/v:DI 135 [ numer ]) 4)
            (const_int 0 [0x0]))) -1 (nil)
    (nil))

and afterwards (divbug.c.06.cse):

(insn 12 6 13 0 (set (reg:SI 137)
        (lt:SI (subreg:SI (reg/f:SI 134) 4)
            (const_int 0 [0x0]))) 60 {*slt_insn} (nil)
    (nil))

The problem is that that substitution is invalid, since (reg/f:SI 134)
doesn't have a second word. Now, I found where the bad substitution is
happening, in canon_reg() in cse.c, which is line 2805 in my version of
the code, the "else" part of:

--
  /* If replacing pseudo with hard reg or vice versa, ensure the
     insn remains valid.  Likewise if the insn has MATCH_DUPs.
  */

  if (insn != 0 && new != 0
      && GET_CODE (new) == REG && GET_CODE (XEXP (x, i)) == REG
      && (((REGNO (new) < FIRST_PSEUDO_REGISTER)
           != (REGNO (XEXP (x, i)) < FIRST_PSEUDO_REGISTER))
          || (insn_code = recog_memoized (insn)) < 0
          || insn_data[insn_code].n_dups > 0))
    validate_change (insn, &XEXP (x, i), new, 1);
  else
    XEXP (x, i) = new;
--

Now though, I am totally stuck trying to figure out why gcc would believe
the substitution to be a sensible thing to do. My speculations are:

 (1) There is a structure-sharing violation somehow, and the whole
(subreg...) should have been changed to the (reg...) rather than just
the child pointer changing.

 (2) There's a random bug somewhere in my machine description, etc.
which is triggering this behaviour.

I can compile the code with an ARM cross-compiler, and the equivalent
substitution doesn't appear to happen (the rtl isn't identical though,
since my arch has significant differences to the ARM).

I don't have much belief in my ability to decipher exactly what's going
on in cse.c, since it's big & complicated & I'm not that smart. Can
anyone lend any pointers as to what might be happening here?

(My machine description files are at:
  http://panic.cs.bris.ac.uk/~jules/dop{.md,.c,.h,-protos.h})

Cheers,

Julian

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

* Re: Bad mode-change inside subreg: DImode to SImode
  2004-03-13 20:10 Bad mode-change inside subreg: DImode to SImode Julian Brown
@ 2004-03-15 16:30 ` Julian Brown
  0 siblings, 0 replies; 2+ messages in thread
From: Julian Brown @ 2004-03-15 16:30 UTC (permalink / raw)
  To: gcc

On 2004-03-13, Julian Brown <brown@cs.bris.ac.uk> wrote:
> Hi,
>
> I am working on a port of GCC to a custom architecture, and I have
> hit a problem recently (possibly since starting working against newer
> versions of GCC) which I am having particular difficulty in solving. I
> am working against the gcc-3_4-branch, but the same thing happens with
> other recent branches.
>
> The following code refuses to compile:
> [snip]

Sorry to follow myself up, the problem turned out to be mishandling of
cumulative args when the function had an aggregate return value. I won't
bother the list with the new bug I've got now, since it looks like
I'm just about the only person who has any interest in sorting out the
little mess that I seem to have made of my port, which isn't a surprise
to me really.

I am slightly in awe of anyone who has managed to get a port off the
ground by themselves, eg Hans-Peter Nilsson with his CRIS & MMIX ports
(and the "Porting GCC for Dunces" document of course). I wonder how many
other people have managed it?

Cheers,

Julian

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

end of thread, other threads:[~2004-03-15 16:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-13 20:10 Bad mode-change inside subreg: DImode to SImode Julian Brown
2004-03-15 16:30 ` Julian Brown

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