This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix for mainline build on mips64el-linux
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 4 May 2006 16:38:10 +0000 (UTC)
- Subject: Fix for mainline build on mips64el-linux
Building a mainline compiler targetting mips64el-linux gets an ICE
building libgcc, in the form of infinite recursion. The test can be
reduced to:
long long ll;
long double ld;
void f(void) { ld = ll; }
The infinite recursion - which happens at expand time - looks like:
#10 0x082f2703 in emit_group_store (orig_dst=0xf7f67a30, src=0xf7f32a30,
type=0x0, ssize=16)
at expr.c:1873
1873 emit_group_store (dst, src, type, ssize);
orig_dst is (reg:TF 197) and src is
(parallel:TF [
(expr_list:REG_DEP_TRUE (reg:DI 32 $f0)
(const_int 0 [0x0]))
(expr_list:REG_DEP_TRUE (reg:DI 34 $f2)
(const_int 8 [0x8]))
])
and the compiler converts this into an integer store.
#9 0x082f29b7 in emit_group_store (orig_dst=0xf7f67a40, src=0xf7f32a30,
type=0x0, ssize=16)
at expr.c:1950
1950 emit_move_insn (dst, temp);
The inner call to emit_group_store enters the case
/* Make life a bit easier for combine. */
/* If the first element of the vector is the low part
of the destination mode, use a paradoxical subreg to
initialize the destination. */
and so calls emit_move_insn.
#8 0x082f60b4 in emit_move_insn (x=0xf7f67a40, y=0xf7f75060)
at expr.c:3278
3278 last_insn = emit_move_insn_1 (x, y);
x is (reg:TI 198) and y is (subreg:TI (reg:DI 199) 0).
#7 0x082f5e75 in emit_move_insn_1 (x=0xf7f67a40, y=0xf7f75060)
at expr.c:3218
3218 return emit_move_multi_word (mode, x, y);
emit_move_insn_1 falls through to emit_move_multi_word to do the TImode
move.
#6 0x082f5bf9 in emit_move_multi_word (mode=TImode, x=0xf7f67a40,
y=0xf7f75060) at expr.c:3147
3147 ypart = operand_subword_force (y, i, mode);
i is 1; operand_subword_force is being used to extract the upper part of
the paradoxical subreg.
#5 0x082c2bd0 in operand_subword_force (op=0xf7f75060, offset=1,
mode=TImode)
at emit-rtl.c:1349
1349 op = force_reg (mode, op);
operand_subword returns 0, so operand_subword_force uses force_reg.
#4 0x082d63ec in force_reg (mode=TImode, x=0xf7f75060)
at explow.c:660
660 insn = emit_move_insn (temp, x);
At this point, we are back to emit_move_insn and recurse indefinitely.
operand_subword returns 0 because simplify_gen_subreg returns 0 (fails to
generate RTL) when asked to return this particular subreg of a paradoxical
subreg (entirely outside the real value inside the paradoxical subreg).
This patch fixes the problem by making simplify_subreg handle this case
and return an rtx for the value 0 instead (given that the bits concerned
are all in the undefined part of a paradoxical subreg). It fixes the
mips64el-linux build, the mips64el-linux test results look reasonable for
all multilibs though I don't have a 4.2 baseline to compare against, and
it bootstraps with no regressions on x86_64-unknown-linux-gnu. OK to
commit?
2006-05-04 Joseph S. Myers <joseph@codesourcery.com>
* simplify-rtx.c (simplify_subreg): Return CONST0_RTX (outermode)
for subreg of a paradoxical subreg entirely outside the innermost
value.
Index: simplify-rtx.c
===================================================================
--- simplify-rtx.c (revision 113499)
+++ simplify-rtx.c (working copy)
@@ -4467,6 +4467,12 @@
final_offset += difference % UNITS_PER_WORD;
}
+ /* If the resulting subreg is entirely outside the inner value,
+ just return 0. */
+ if (final_offset >= GET_MODE_SIZE (innermostmode)
+ || final_offset <= -GET_MODE_SIZE (outermode))
+ return CONST0_RTX (outermode);
+
/* See whether resulting subreg will be paradoxical. */
if (GET_MODE_SIZE (innermostmode) > GET_MODE_SIZE (outermode))
{
--
Joseph S. Myers
joseph@codesourcery.com