Bug 27405 - [4.2/4.3 Regression] gcc.c-torture/execute/960209-1.c ICEs on sh64-* with -O3
Summary: [4.2/4.3 Regression] gcc.c-torture/execute/960209-1.c ICEs on sh64-* with -O3
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.2.0
: P5 normal
Target Milestone: 4.2.1
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2006-05-03 00:58 UTC by Kazumoto Kojima
Modified: 2007-05-21 01:00 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: sh64-elf
Build: i686-pc-linux-gnu
Known to work: 4.1.0
Known to fail:
Last reconfirmed: 2006-05-08 19:44:04


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kazumoto Kojima 2006-05-03 00:58:35 UTC
gcc.c-torture/execute/960209-1.c fails at -O3 with the ICE:

960209-1.c:36: error: unrecognizable insn:
(insn:HI 206 103 184 17 (set (subreg:DI (reg:SI 205) 0)
        (reg:DI 215)) -1 (nil)
    (nil))

It seems that this move insn is generated at loop-invariant.c:
move_invariant_reg().
Comment 1 Jorn Wolfgang Rennecke 2006-05-08 19:44:03 UTC
(In reply to comment #0)
> It seems that this move insn is generated at loop-invariant.c:
> move_invariant_reg().

Yes.  In general, we say that we don't want such SUBREGS to appear in the
first place, since then they could be propagated by the optimizers into
contexts where they don't belong.
However, that has already happened in this case.  THe subreg originally
appeared in:

(insn 183 204 184 17 (set (subreg:DI (reg:SI 205) 0)
        (gt:DI (reg/v:SI 169 [ q ])
            (reg:SI 210))) 14 {cmpgtsi_media} (nil)
    (nil))

In this context, the SUBREG is fine, because equality / inequality comparison
operators can generate only 0 or 1.  And tere is also a good reason to have
these operator always generate the same mode: this is required in order for
cse to function properly.

I don't think recognizing the move in insn 206 is the right way forward; the
subreg be further propagated into contexts where it does not belong.

Another approach would be to say that the loop invariant motion code should
have uses an SImode register, since the destination of the original instruction
was also ultimately an SIMode register.  However, that would mean that we
couldn't share the invariant with other uses where an DImode comparison result
is wanted.

The problem is that we loose information when we say that the result of the
comparison is DImode: we don't know any more that the value is suitable
for SImode without sign-extension.
On the other hand, if an SImode value is held in a general purpose register,
we know that we can use this register to get the sign-extended DImode value.

Thus, I think the right solution is to change the SHmedia setCC insns to
generate SImode values.  That will mean that for DImode there will initially be ianother temporary register, and an extra sign extension insn.  We'll have
to check that SI->DI sign extensions can be folded into all the uses that
matter - arith_reg_operand already allows them, so where
that predicate is used (directly or indirectly), we should be fine.
Comment 2 Mark Mitchell 2006-06-04 18:44:59 UTC
SH is not a primary or secondary platform.
Comment 3 Kazumoto Kojima 2006-11-02 22:57:23 UTC
Subject: Bug 27405

Author: kkojima
Date: Thu Nov  2 22:57:13 2006
New Revision: 118435

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=118435
Log:
	PR target/27405
	* config/sh/sh.md (cmp{eq,gt,gtu}{si,di}_media): Remove.
	(cmpsi{eq,gt,gtu}{si,di}_media): Rename to
	cmp{eq,gt,gtu}{si,di}_media.
	(*cmpne0si_media): Remove.
	(*movsicc_umin): Adjust gen_cmp*_media call.
	(unordered): Change the mode of unordered and operands[1] to
	SImode.
	(seq): Adjust gen_cmp*_media calls.  Make the mode of
	a temporary result of compare SImode if needed.  If the mode
	of operands[0] is DImode, extend the temporary result to DImode.
	(slt, sle, sgt, sge, sgtu, sltu, sleu, sgue, sne): Likewise.
	(sunorderd): Change the mode of match_operand and unorderd to
	SImode.
	(cmpeq{sf,df}_media): Remove.
	(cmpsieq{sf,df}_media): Rename to cmpeq{sf,df}_media.
	(cmp{gt,ge,un}{sf,df}_media): Change the mode of match_operand
	and compare operation to SImode.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/sh/sh.md

Comment 4 patchapp@dberlin.org 2006-11-05 20:36:25 UTC
Subject: Bug number PR target/27405

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-11/msg00053.html
Comment 5 Mark Mitchell 2007-05-14 22:28:16 UTC
Will not be fixed in 4.2.0; retargeting at 4.2.1.
Comment 6 Kazumoto Kojima 2007-05-21 00:14:00 UTC
Subject: Bug 27405

Author: kkojima
Date: Sun May 20 23:13:48 2007
New Revision: 124879

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=124879
Log:
	PR target/27405
	Backport from mainline.
	* config/sh/sh.md (cmp{eq,gt,gtu}{si,di}_media): Remove.
	(cmpsi{eq,gt,gtu}{si,di}_media): Rename to
	cmp{eq,gt,gtu}{si,di}_media.
	(*cmpne0si_media): Remove.
	(*movsicc_umin): Adjust gen_cmp*_media call.
	(unordered): Change the mode of unordered and operands[1] to
	SImode.
	(seq): Adjust gen_cmp*_media calls.  Make the mode of
	a temporary result of compare SImode if needed.  If the mode
	of operands[0] is DImode, extend the temporary result to DImode.
	(slt, sle, sgt, sge, sgtu, sltu, sleu, sgue, sne): Likewise.
	(sunorderd): Change the mode of match_operand and unorderd to
	SImode.
	(cmpeq{sf,df}_media): Remove.
	(cmpsieq{sf,df}_media): Rename to cmpeq{sf,df}_media.
	(cmp{gt,ge,un}{sf,df}_media): Change the mode of match_operand
	and compare operation to SImode.


Modified:
    branches/gcc-4_2-branch/gcc/ChangeLog
    branches/gcc-4_2-branch/gcc/config/sh/sh.md

Comment 7 Kazumoto Kojima 2007-05-21 01:00:41 UTC
Fixed.