[Bug rtl-optimization/35232] [4.3 regression] ICE in fp-int-convert-double.c at -O2
rsandifo at nildram dot co dot uk
gcc-bugzilla@gcc.gnu.org
Sun Feb 17 22:13:00 GMT 2008
------- Comment #2 from rsandifo at nildram dot co dot uk 2008-02-17 22:13 -------
Subject: Re: [4.3 regression] ICE in fp-int-convert-double.c at -O2
"ubizjak at gmail dot com" <gcc-bugzilla@gcc.gnu.org> writes:
> IMO is a bit suspicious that FP<->int conversions in mips.md operate on both FP
> operands, i.e:
>
> (define_insn "fix_truncdfsi2_insn"
> [(set (match_operand:SI 0 "register_operand" "=f")
> (fix:SI (match_operand:DF 1 "register_operand" "f")))]
>
> ...and similar patterns... , as well as:
>
> (define_insn "floatsidf2"
> [(set (match_operand:DF 0 "register_operand" "=f")
> (float:DF (match_operand:SI 1 "register_operand" "f")))]
>
> ...and similar patterns.
>
> One would expect a constraint that describes integer regs for output
> operand in the former case and integer regs for input operand in the
> later case.
I don't see why. The MIPS insns in question operate on FP regs only.
"f" just denotes a class of register: it doesn't indicate an FP mode.
Anyway, it was indeed a reload inheritance bug. We have an insn:
(insn 1749 1748 1750 193
../../../gcc/gcc/testsuite/gcc.dg/torture/fp-int-conver
t-double.c:12 (set (reg:SI 1475 [ ivout.331+-3 ])
(zero_extend:SI (reg:QI 2209 [ ivout ]))) 147
{*zero_extendqisi2_mips16e
} (expr_list:REG_DEAD (reg:QI 2209 [ ivout ])
(nil)))
and MIPS16 zero extensions require the input operand to match the output.
The insn gets the following reload:
Reloads for insn # 1749
Reload 0: reload_in (QI) = (reg:QI 2 $2 [orig:2209 ivout ] [2209])
reload_out (SI) = (reg:SI 1475 [ ivout.331+-3 ])
M16_REGS, RELOAD_OTHER (opnum = 0)
reload_in_reg: (reg:QI 2 $2 [orig:2209 ivout ] [2209])
reload_out_reg: (reg:SI 1475 [ ivout.331+-3 ])
reload_reg_rtx: (reg:QI 2 $2 [orig:2209 ivout ] [2209])
Note that the reload_reg_rtx is QImode. This is valid, because
(reg:QI 2) and (reg:SI 2) occupy the same number of registers
(and the code that chose (reg:QI 2) did check this). But we
then record inheritance information as though we had a
(reg:SI 1475) <- (reg:QI 2) copy, and get confused later when
we expect the source to have SImode instead of QImode.
You can see the same thing in a wrong-code scenario with this
32-bit MIPS testcase:
--------------------------------------------------------------------
__attribute__((nomips16)) unsigned int
f1 (unsigned long long x)
{
unsigned int r;
asm ("# %0" : "=a" (r) : "0" (x));
asm ("# %0" : "=h" (r) : "0" (r));
return r;
}
__attribute__((nomips16)) unsigned int
f2 (unsigned long long x)
{
unsigned int r;
asm ("# %0" : "=a" (r) : "0" (x));
asm ("# %0" : "=l" (r) : "0" (r));
return r;
}
int
main (void)
{
return f1 (4) != 4 || f2 (4) != 4;
}
--------------------------------------------------------------------
(one function for each endianness). Here we have an in-out reload
with a 64-bit input (x) and a 32-bit output (r), so the reload register
itself is 64 bits wide. emit_output_reload_insns correctly adjusts
the reload register for the output mode, but we record inheritance
as though the copy used an unadjusted register. In other words,
we effectively record a 64-bit-to-32-bit copy instead of a 32-bit copy.
Despite the mode mismatch, we fluke correct output for one endianness,
but we get the wrong half of the register with the other endianness.
I'm testing a patch.
Richard
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35232
More information about the Gcc-bugs
mailing list