------- 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" <[EMAIL PROTECTED]> 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