[LLVMdev] Help with definition of subregisters; spill, rematerialization and implicit uses

Mikael Holmén mikael.holmen at ericsson.com
Fri Aug 22 05:17:53 PDT 2014


Hi Quentin,

On 08/19/14 18:58, Quentin Colombet wrote:
[...]
> It seems that you will have to debug further the *** Bad machine code: Instruction loads from dead spill slot *** before we can be of any help.

Yes, I've done some more digging. Sorry for the long mail...

I get:

  Inline spilling aN40_0_7:%vreg1954 [5000r,5056r:0)[5056r,5348r:1) 
0 at 5000r 1 at 5056r

At this point I have the following live ranges for vreg1954:

  %vreg1954 [5000r,5056r:0)[5056r,5348r:1)  0 at 5000r 1 at 5056r

And vreg1954 is mentioned in these instructions:

  5000B		%vreg1954:hi16<def,read-undef> = mv_any16 32766
  [...]
  5048B		mv_ar16_r16_rmod1 %vreg1954:hi16, %vreg1753
  5056B		%vreg1954:lo16<def> = mv_nimm6_ar16 0
  5064B		Store40FI %vreg1954, <fi#2>
  [...]
  5128B		%vreg223<def> = COPY %vreg1954
  [...]
  5216B		%vreg1178<def> = COPY %vreg1954
  [...]
  5348B		%vreg1955<def> = COPY %vreg1954

Then it tries to rematerialize:

  Value %vreg1954:0 at 5000r may remat from %vreg1954:hi16<def,read-undef> 
= mv_any16 32766

And it examines all use points of vreg1954 to see if it can remat or not:

	cannot remat for 5128e	%vreg223<def> = COPY %vreg1954
	cannot remat for 5216e	%vreg1178<def> = COPY %vreg1954
	remat:  5044r	%vreg1956:hi16<def,read-undef> = mv_any16 32766
	        5048e	mv_ar16_r16_rmod1 %vreg1956:hi16<kill>, %vreg1753

	cannot remat for 5064e	Store40FI %vreg1954, <fi#2>
	cannot remat for 5348e	%vreg1955<def> = COPY %vreg1954
  All defs dead: %vreg1954:hi16<def,read-undef,dead> = mv_any16 32766
  Remat created 1 dead defs.
  Deleting dead def 5000r	%vreg1954:hi16<def,read-undef,dead> = mv_any16 
32766
  1 registers to spill after remat.

What strikes me here is that it never mentions the instruction

  5056B		%vreg1954:lo16<def> = mv_nimm6_ar16 0

where we do have a read of vreg1954:hi16 since there is no read-undef on 
the def operand.

Is this how it's intended to be?

(The use points are found by

     for (MachineRegisterInfo::use_bundle_nodbg_iterator
          RI = MRI.use_bundle_nodbg_begin(Reg), E = 
MRI.use_bundle_nodbg_end();
          RI != E; ) {
       anyRemat |= reMaterializeFor(LI, MI);
     }

and

  MachineRegisterInfo::defusechain_instr_iterator::advance

seems to skip all def operands for use_bundle_nodbg_iterator since 
ReturnDefs is false. So it will happily advance past the instruction 
setting lo16.)

Then after the remats it does

  spillAroundUses %vreg1954

and there I get

	reload:   5052r	%vreg1957<def> = Load40FI <fi#2>
	rewrite: 5056r	%vreg1957:lo16<def> = mv_nimm6_ar16 0

since no remat was inserted before 5056. But noone has stored anything 
at fi#2 so I end up with

  *** Bad machine code: Instruction loads from dead spill slot ***

Does everything above, except the error at the end, look ok to you?


I tried fiddling with MachineRegisterInfo::defusechain_instr_iterator to 
make it also return the

  %vreg1954:lo16<def> = mv_nimm6_ar16 0

instruction, and then my program actually compiled succesfully!

My diff:

@@ -886,11 +886,11 @@ public:
      explicit defusechain_instr_iterator(MachineOperand *op) : Op(op) {
        // If the first node isn't one we're interested in, advance to 
one that
        // we are interested in.
        if (op) {
          if ((!ReturnUses && op->isUse()) ||
-            (!ReturnDefs && op->isDef()) ||
+            (!ReturnDefs && op->isDef() && !op->readsReg()) ||
              (SkipDebug && op->isDebug()))
            advance();
        }
      }
      friend class MachineRegisterInfo;
@@ -907,11 +907,11 @@ public:
            else
              assert(!Op->isDebug() && "Can't have debug defs");
          }
        } else {
          // If this is an operand we don't care about, skip it.
-        while (Op && ((!ReturnDefs && Op->isDef()) ||
+        while (Op && ((!ReturnDefs && Op->isDef() && !Op->readsReg()) ||
                        (SkipDebug && Op->isDebug())))
            Op = getNextOperandForReg(Op);
        }
      }
    public:


But of course then other tests fail. For example:

  build-all/./bin/llc < test/CodeGen/R600/literals.ll -march=r600 
-mcpu=redwood

gives

llc: ../lib/CodeGen/TwoAddressInstructionPass.cpp:684: void (anonymous 
namespace)::TwoAddressInstructionPass::scanUses(unsigned int): Assertion 
`SrcRegMap[NewReg] == Reg && "Can't map to two src registers!"' failed.

So I suppose there are assumptions that defusechain_instr_iterator 
ignores implicit sub register use when defining some sub register. :/

What's your thoughts on this?

Thanks,
Mikael



More information about the llvm-dev mailing list