[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[Bug target/29825] [4.1 regression] ICE in extract_insn, at recog.c:2084




------- Comment #11 from rguenth at gcc dot gnu dot org  2006-11-14 11:11 -------
The reduced testcase only fails on i?86, bootstrap also fails on x86_64 with
the same error.

At least (symbol_ref:SI ("dwarf_reg_size_table") [flags 0x2] <var_decl
0x2af3f74a6580 dwarf_reg_size_table>) is not a valid PIC address (it's only one
in 64bit mode).

from loop.c we enter ix86_expand_move (via gen_movis) with an operand1 of

(unspec:SI [
        (symbol_ref:SI ("dwarf_reg_size_table") [flags 0x2] <var_decl
0x2b38cd3da580 dwarf_reg_size_table>)
    ] 1)

which we don't handle.

We reach there through loop.c:gen_add_mult called with

#11 0x000000000091e99b in gen_add_mult (b=0x2b38cd2ee410, m=0x2b38cd2ee410, 
    a=0x2b38cd49bdc0, reg=0x2b38cd49bd20)
    at /space//rguenther/src/svn/gcc-4_1-branch/gcc/loop.c:9223
9223      result = expand_mult_add (b, reg, m, a, GET_MODE (reg), 1);
(gdb) call debug_rtx (b)
(const_int 1 [0x1])
(gdb) call debug_rtx (m)
(const_int 1 [0x1])
(gdb) call debug_rtx (a)
(plus:SI (plus:SI (reg:SI 3 bx)
        (const_int -1 [0xffffffffffffffff]))
    (const:SI (unspec:SI [
                (symbol_ref:SI ("dwarf_reg_size_table") [flags 0x2] <var_decl
0x2b38cd3da580 dwarf_reg_size_table>)
            ] 1)))
(gdb) call debug_rtx (reg)
(reg:SI 82)

via expmed.c:expand_mult_add we go through expanding a tree (ugh) which looks
then like

(gdb) call debug_tree (result)
 <plus_expr 0x2b38cd499410
    type <integer_type 0x2b38cd2f8580 unsigned int public unsigned SI
        size <integer_cst 0x2b38cd2e9a50 constant invariant 32>
        unit size <integer_cst 0x2b38cd2e9570 constant invariant 4>
        align 32 symtab 0 alias set -1 precision 32 min <integer_cst
0x2b38cd2e9b40 0> max <integer_cst 0x2b38cd2e9b10 4294967295>>

    arg 0 <var_decl 0x2b38cd49c210 D.1348 type <integer_type 0x2b38cd2f8580
unsigned int>
        used unsigned SI file t.i line 16 size <integer_cst 0x2b38cd2e9a50 32>
unit size <integer_cst 0x2b38cd2e9570 4>
        align 32
        (reg:SI 3 bx)>
    arg 1 <var_decl 0x2b38cd49c160 D.1347 type <integer_type 0x2b38cd2f8580
unsigned int>
        used unsigned SI file t.i line 16 size <integer_cst 0x2b38cd2e9a50 32>
unit size <integer_cst 0x2b38cd2e9570 4>
        align 32
        (unspec:SI [
        (symbol_ref:SI ("dwarf_reg_size_table") [flags 0x2] <var_decl
0x2b38cd3da580 dwarf_reg_size_table>)
    ] 1)>>

which is where we get the plain UNSPEC from.  In loop.c:scan_loop we
propagate the load into its use which is the start of the problems.

We then call validate_replace_rtx with
(gdb) call debug_rtx (from)
(reg/f:SI 72)
(gdb) call debug_rtx (to)
(plus:SI (reg:SI 3 bx)
    (const:SI (unspec:SI [
                (symbol_ref:SI ("dwarf_reg_size_table") [flags 0x2] <var_decl
0x2b22d66b7580 dwarf_reg_size_table>)
            ] 1)))
(gdb) call debug_rtx (insn)
(insn 32 31 34 (parallel [
            (set (reg:SI 71)
                (plus:SI (reg:SI 66 [ ivtmp.32 ])
                    (reg/f:SI 72)))
            (clobber (reg:CC 17 flags))
        ]) 208 {*addsi_1} (nil)
    (nil))

In loop.c we go through lengths of discovering REG_EQUAL notes supposedly
to use them as src in those operations.  And indeed

Index: loop.c
===================================================================
*** loop.c      (revision 118809)
--- loop.c      (working copy)
*************** scan_loop (struct loop *loop, int flags)
*** 1313,1326 ****
                      && ! modified_between_p (SET_SRC (set), p, user)
                      && no_labels_between_p (p, user)
                      && validate_replace_rtx (SET_DEST (set),
!                                              SET_SRC (set), user))
                    {
                      /* Replace any usage in a REG_EQUAL note.  Must copy
                         the new source, so that we don't get rtx sharing
                         between the SET_SOURCE and REG_NOTES of insn p.  */
                      REG_NOTES (user)
                        = replace_rtx (REG_NOTES (user), SET_DEST (set),
!                                      copy_rtx (SET_SRC (set)));

                      delete_insn (p);
                      for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set));
--- 1313,1326 ----
                      && ! modified_between_p (SET_SRC (set), p, user)
                      && no_labels_between_p (p, user)
                      && validate_replace_rtx (SET_DEST (set),
!                                              src, user))
                    {
                      /* Replace any usage in a REG_EQUAL note.  Must copy
                         the new source, so that we don't get rtx sharing
                         between the SET_SOURCE and REG_NOTES of insn p.  */
                      REG_NOTES (user)
                        = replace_rtx (REG_NOTES (user), SET_DEST (set),
!                                      copy_rtx (src));

                      delete_insn (p);
                      for (i = 0; i < LOOP_REGNO_NREGS (regno, SET_DEST (set));

seems to fix this particular testcase.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29825

------- You are receiving this mail because: -------
You reported the bug, or are watching the reporter.



Reply to: