This is the mail archive of the gcc@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]

IRA: Broken live ranges for clobbered inputs


Hi,

I'm debugging the S/390 bootstrap problem and stumbled over an IRA
behaviour which I don't quite understand.

The following code in process_bb_node_lives ira-lives.c makes sure
that for clobbered regs which are also used for inputs the proper
conflicts are recorded:

static bool
def_conflicts_with_inputs_p (struct df_ref *def)
{
  /* Conservatively assume that the condition is true for all clobbers.  */
  return DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER);
}

...
	  /* If any defined values conflict with the inputs, mark those
	     defined values as live.  */
	  for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
	    if (def_conflicts_with_inputs_p (*def_rec))
	      mark_ref_live (*def_rec);

	  process_single_reg_class_operands (true, freq);
	  
	  /* See which of the defined values we marked as live are dead
	     before the instruction.  */
	  for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
	    if (def_conflicts_with_inputs_p (*def_rec))
	      mark_ref_dead (*def_rec);

	  curr_point++;
	}
...

So going backwards through the INSNs this basically ends all live
ranges for input regs which are also clobbered in that INSN, but how
can this be correct?

On S/390 we e.g. generate INSNs like:

(insn:QI 58 145 61 4 t.c:58 (parallel [
            (clobber (reg/f:DI 1 %r1 [orig:71 D.1262 ] [71]))
            (clobber (reg:DI 3 %r3 [orig:72 D.1292 ] [72]))
            (set (reg:CCU 33 %cc)
                (compare:CCU (mem:BLK (reg/f:DI 1 %r1 [orig:71 D.1262 ] [71]) [0 A8])
                    (mem:BLK (reg:DI 3 %r3 [orig:72 D.1292 ] [72]) [0 A8])))
            (use (reg:SI 0 %r0))
        ]) 95 {*cmpstrdi} (nil))

The CLOBBERs make sure that the values of r71 and r72 aren't used
beyond that insn since these values are overwritten by the instruction
used to implement this.  The code above makes the live ranges of r71
and r72 to be limited to that insn so both are dead before that INSNs
what leads to r3 to be assigned to pseudos which would normally
conflict.

The result is a miscompile of genpreds what currently breaks S/390
bootstrap.

I think the second loop should only mark the registers dead which have
been marked live before without being already live at that point.

Bye,

-Andreas-


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