This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/14927] [ia64] ICE in gen_movxf
- From: "wilson at specifixinc dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 23 Apr 2004 06:17:55 -0000
- Subject: [Bug target/14927] [ia64] ICE in gen_movxf
- References: <20040412185358.14927.schwab@suse.de>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From wilson at specifixinc dot com 2004-04-23 06:17 -------
Subject: Re: New: [ia64] ICE in gen_movxf
schwab at suse dot de wrote:
> scalar-by-value-3_x.i: In function `testitcld':
> scalar-by-value-3_x.i:6: internal compiler error: in gen_movxf, at
This is a long latent SUBREG problem, going back at least 4 years to
when some of the long double code was originally added.
The movxf pattern fails to handle the case where operands[0] is a SUBREG
of a GR reg. While looking at the code, I noticed a second latent
problem. There is one place where we are accidentally applying
SUBREG_REG to a GR reg. I tried to fix that too, though I don't have a
testcase for it.
The following patch works for this testcase, but is as yet untested.
2004-04-22 James E Wilson <wilson@specifixinc.com>
* config/ia64/ia64.md (movxf): New local op0. Handle case where
operands[0] is a SUBREG. Handle case where operands[1] is a GR reg.
Index: ia64.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.md,v
retrieving revision 1.128
diff -p -r1.128 ia64.md
*** ia64.md 21 Apr 2004 01:39:17 -0000 1.128
--- ia64.md 23 Apr 2004 06:12:47 -0000
***************
*** 677,688 ****
(match_operand:XF 1 "general_operand" ""))]
""
{
/* We must support XFmode loads into general registers for stdarg/vararg
and unprototyped calls. We split them into DImode loads for convenience.
We don't need XFmode stores from general regs, because a stdarg/vararg
routine does a block store to memory of unnamed arguments. */
! if (GET_CODE (operands[0]) == REG
! && GR_REGNO_P (REGNO (operands[0])))
{
/* We're hoping to transform everything that deals with XFmode
quantities and GR registers early in the compiler. */
--- 677,693 ----
(match_operand:XF 1 "general_operand" ""))]
""
{
+ rtx op0 = operands[0];
+
+ if (GET_CODE (op0) == SUBREG)
+ op0 = SUBREG_REG (op0);
+
/* We must support XFmode loads into general registers for stdarg/vararg
and unprototyped calls. We split them into DImode loads for convenience.
We don't need XFmode stores from general regs, because a stdarg/vararg
routine does a block store to memory of unnamed arguments. */
!
! if (GET_CODE (op0) == REG && GR_REGNO_P (REGNO (op0)))
{
/* We're hoping to transform everything that deals with XFmode
quantities and GR registers early in the compiler. */
***************
*** 695,710 ****
|| (GET_CODE (operands[1]) == REG
&& GR_REGNO_P (REGNO (operands[1]))))
{
! emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
! SUBREG_REG (operands[1]));
DONE;
}
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
! emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
operand_subword (operands[1], 0, 0, XFmode));
! emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
operand_subword (operands[1], 1, 0, XFmode));
DONE;
}
--- 700,722 ----
|| (GET_CODE (operands[1]) == REG
&& GR_REGNO_P (REGNO (operands[1]))))
{
! rtx op1 = operands[1];
!
! if (GET_CODE (op1) == SUBREG)
! op1 = SUBREG_REG (op1);
! else
! /* ??? Maybe we should make a SUBREG here? */
! op1 = gen_rtx_REG (TImode, REGNO (op1));
!
! emit_move_insn (gen_rtx_REG (TImode, REGNO (op0)), op1);
DONE;
}
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
! emit_move_insn (gen_rtx_REG (DImode, REGNO (op0)),
operand_subword (operands[1], 0, 0, XFmode));
! emit_move_insn (gen_rtx_REG (DImode, REGNO (op0) + 1),
operand_subword (operands[1], 1, 0, XFmode));
DONE;
}
***************
*** 717,724 ****
{
rtx out[2];
! out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
! out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
--- 729,736 ----
{
rtx out[2];
! out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0));
! out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0) + 1);
emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14927