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 rtl-optimization/48633] New: IRA causes ICE in compensate_edge


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

           Summary: IRA causes ICE in compensate_edge
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: matz@gcc.gnu.org


Since r172516 the Ada testcase cxg2001 fails with an ICE in compensate_edge
on x86_64-linux.

The problem is not specific to Ada an can be reproduced with a C++ testcase
simulating what Ada does.  This testcase does not need the patch from r172516
and also fails before:

% cat ira-bug.cc
/* { dg-do compile} */
/* { dg-options "-O2 -fira-region=all -fnon-call-exceptions" } */
extern long double getme (void);
extern void useme (long double);
struct Frame {
    long double tmp;
};
void bugme (int n)
{
  Frame f;
  int i;
  f.tmp = getme();
  try {
    for (i = 0; i < n; i++)
      {
        f.tmp += 1.0;
      }
  } catch (...) {
    f.tmp += 1.0;
  }
  useme (f.tmp);
}

% ./cc1plus -O2 -fnon-call-exceptions -fira-region=all ira-bug.cc
ira-bug.cc: In function âvoid bugme(int)â:
ira-bug.cc:22:1: internal compiler error: in compensate_edge, at
reg-stack.c:2781

-fnon-call-exceptions is needed as Ada effectively sets it, -fira-region=all
is needed to make IRA fail on this small testcase, otherwise IRA assigned
registers for the subloops here due to low reg pressure.  The Ada testcase
has much higher pressure causing IRA to go into the same code-paths as
with ira-region=all.

The problem is the allocation of pseudo 61 to hardreg 10 (a stackreg).
pseudo 61 gets two allocnos, a1 for loop0 which conflicts with the stackregs
because it's live over abnormal edges, and a8 for loop1 which doesn't
conflict with those stackregs (which is okay).

The problem is the transition from loop1 (a8 alloced to hardreg 10) to loop0
(a1, spilled), which requires a memory store from h10 to stack.  But the
transition itself goes over an EH edge, and the compensation code is inserted
into the EH block:

(code_label/s 65 36 67 11 8 "" [1 uses])

(note 67 65 84 11 [bb 11] NOTE_INSN_BASIC_BLOCK)

(insn 84 67 40 11 (set (mem/c:XF (plus:DI (reg/f:DI 7 sp)
                (const_int 32 [0x20])) [4 %sfp+-16 S16 A128])
        (reg:XF 10 st(2) [orig:61 f$tmp ] [61])) 105 {*movxf_internal}
     (nil))

This is the compensation code, requiring hardreg 10 to be set, but this
bb 11 is the target of an EH edge.  This then later is checked in the
reg-stack pass and asserts.

The IRA dump is somewhat interesting:

  Loop 0 (parent -1, header bb0, depth 0)
    bbs: 12 11 10 9 8 7 3(->5:l1) 2
    all: 0r62 1r61 2r73 3r70 4r69 5r74 6r63 7r66
    modified regnos: 61 62 63 66 69 70 73 74
    border:
    Pressure: GENERAL_REGS=2 FLOAT_REGS=4
    Hard reg set forest:
      0:( 0-6 8-15 21-51)@0
        1:( 0-6 37-44)@24004
          2:( 0 3 5 6 41-44)@14
        3:( 8-15)@60040
      Spill a1(r61,l0)

So, for loop0 r61 is spilled, fine.

  Loop 1 (parent 0, header bb5, depth 1)
    bbs: 6(->7:l0) 5(->11:l0) 4

So we have two exits from this region, via 6->7 (the normal loop exit)
and via 5->11 (the EH edge).

    all: 8r61 9r63 10r66 11r73 12r74 13r62
    modified regnos: 61 62 63
    border: 8r61 9r63 10r66 11r73 12r74 13r62
    Pressure: GENERAL_REGS=2 FLOAT_REGS=4
    Hard reg set forest:
      0:( 0-6 8-15 21-51)@0
        1:( 0-6 37-44)@22920
        2:( 8 10-15)@72856
      Allocno a8r61 of FLOAT_REGS(8) has 7 avail. regs 8 10-15
      ...
      Popping a8(r61,l1)  -- assign reg 10

So, r61 in the loop gets hardreg 10.  Then we go on:

New iteration of spill/restore move
      Changing RTL for loop 1 (header bb5)
  10 vs parent -1:      Creating newreg=75 from oldreg=61

So, it noticed that the two regions have different dispositions for the
same pseudo, and generates compensation code:

rescanning insn with uid = 18.
deleting insn with uid = 18.
rescanning insn with uid = 7.
deleting insn with uid = 7.
scanning new insn with uid = 84.

insn 84 is the compensation code, and it's placed in a region where the source
(a8 == hardreg 10) isn't live anymore.


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