This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/27883] [4.2 regression] in schedule_insns, at sched-rgn.c:3038 on mips



------- Comment #4 from wilson at gcc dot gnu dot org  2006-06-27 03:02 -------
This only fails for --enable-checking builds, which is the default for
mainline, but not release branches.  I was able to reproduce this with gcc-4.0,
but not gcc-3.4.  The difference between the two is that gcc-4.0 has the
__builtin_copysign support, which emits the RTL that triggers the error.  The
error has probably been latent for a while.

The insn that causes the problem is
(jump_insn 99 98 113 15 (set (pc)
        (if_then_else (ge:SI (subreg:SI (reg:DF 32 $f0) 4)
                (const_int 0 [0x0]))
            (label_ref 101)
            (pc))) 261 {*branch_zerosi} (insn_list:REG_DEP_TRUE 94 (nil))
    (expr_list:REG_DEAD (reg:SI 33 $f1)
        (expr_list:REG_BR_PROB (const_int 5000 [0x1388])
            (nil))))
On a 32-bit mips target, DFmode $f0 is a register pair $f0/$f1, so technically
this is correct.  There is a corresponding REG_UNUSED for $f0 on the insn that
sets (reg:DF 32 $f0).

However, flow doesn't track individual regs in subregs, it only tracks the
whole subreg.  Note that mark_used_reg ignores subregs.  So when we execute the
second life pass, we end up with
(jump_insn 98 97 112 17 (set (pc)
        (if_then_else (ge (subreg:SI (reg:DF 32 $f0) 4)
                (const_int 0 [0x0]))
            (label_ref 100)
            (pc))) 271 {*branch_ordersi} (insn_list:REG_DEP_TRUE 93 (nil))
    (expr_list:REG_DEAD (reg:DF 32 $f0)
        (expr_list:REG_DEAD (reg:SI 33 $f1)
            (expr_list:REG_BR_PROB (const_int 5000 [0x1388])
                (nil)))))
Note that we now have two overlapping REG_DEAD notes plus an overlapping
REG_UNUSED note on a previous insn.  When sched runs, it deletes both REG_DEAD
notes, but only readds one, resulting in the abort for a REG_DEAD note
consistency problem.

A subreg of a hard register is normally not allowed, but it is created in this
case because CANNOT_CHANGE_CLASS_MODE is defined, and HARD_REGNO_MODE_OK says
that an SImode $f1 is not OK.  The result is that simplify_subreg doesn't
simplify this.  The other part is that register_operand says it is OK. 
Eventually, this gets fixed by reload.

Fixing combine to get this right looks complicated.  Combine has to know that
the register was used inside a subreg, and then figure out that the subreg
wasn't simplified because of CANNOT_CHANGE_CLASS_MODE, etc.

I think a simpler solution here is to note that the life2 pass would have
worked correctly if it deleted all prior REG_UNUSED/REG_DEAD notes before it
started.  Incidentally, the comments for the life2 pass say it was explicitly
added to fix REG_UNUSED/REG_DEAD problems with distribute_notes in combine, so
it was apparently added to fix a related problem.  It just isn't working the
way it was originally intended.

It is curious that life2 is running immediately before sched, instead of
immediately after combine.  If we ran it immediately after combine, we could
get rid of the REG_DEAD/REG_UNUSED support in distribute_notes, which is
probably the most complicated, and most buggy, part of combine.  This would
also speed up the compiler a little bit.


-- 

wilson at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |wilson at gcc dot gnu dot
                   |                            |org
             Status|UNCONFIRMED                 |NEW
     Ever Confirmed|0                           |1
   Last reconfirmed|0000-00-00 00:00:00         |2006-06-27 03:02:40
               date|                            |


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]