Debugging/Fixing 'Interval not live at use' errors

I have a target backend which is currently causing live interval analysis to throw ‘Interval not live at use’ errors for many of my benchmarks. I imagine that this is caused by missing information for my target (probably in the instructioninfo tablegen?), but I am having difficulties in both debugging and fixing this problem, and would appreciate any advice or help anyone can give.

I’m unsure if it’s actually relevant, but the particular MachineInstr that is involved when the assertion is thrown is always a LDrli (load from an address given by a register + 32-bit immediate, to a register), which is defined as:

def LDrli : Pseudo<(outs CPURegs:$dst), (ins MEMrli:$addr),
“ld $dst,$addr”,
[(set CPURegs:$dst, (load ADDRrli:$addr))]>;

Where ADDRrli and MEMrli are:

def ADDRrli : ComplexPattern<i32, 2, “SelectADDRrli”, [frameindex], []>;

// Register + long immediate.
def MEMrli : Operand {
let PrintMethod = “printMemOperand”;
let MIOperandInfo = (ops CPURegs, limm32);
}

Does anyone have any suggestions on how to debug this issue, or what information a target must be giving to allow live interval analysis to work ok? (Possibly register clobbering information or the like?)

Thanks,
Stephen

Probably, -verify-machineinstrs will tell you what’s wrong.

/jakob

Thanks for the suggestion. I ran verify-machineinstrs and found that I’ve definitely been doing something wrong, for quite a while at least (I assume that live interval analysis and the particular benchmark just happened to expose it). Results are at http://pastebin.com/5zeUDVXK.

I’m not entirely sure what is wrong here - I assume it has something to do with my ‘special’ instruction LDri_ab. This instruction is a load with an ‘address writeback’ - ld.ab r0, [r1, 5] is equivalent to ld r0, [r1]; add r1, r1, 5. As it was very difficult to match such behaviour automatically, I actually only generate them manually for prologue/epilogue emission, so the tablegen def is like:

def LDri_ab : Pseudo<(outs CPURegs:$src), (ins MEMri:$addr),
“ld.ab $src,$addr”,
[]>;

I’m guessing that the warning is because such an instruction doesn’t tell LLVM what it uses nor what it kills? Is there a way I can do this? Alternatively, if the reason is something else, I’d be happy to know that too ;).

Stephen

Hi Stephen,

I'm not entirely sure what is wrong here - I assume it has something to do
with my 'special' instruction LDri_ab. This instruction is a load with an
'address writeback' - ld.ab r0, [r1, 5] is equivalent to ld r0, [r1]; add
r1, r1, 5. As it was very difficult to match such behaviour automatically, I
actually only generate them manually for prologue/epilogue emission, so the
tablegen def is like:

That fits. This line

LDri_ab %FP, %SP, 4

should almost certainly be printed as:

%FP = LDri_ab %SP, 4

The most likely cause is a slightly malformed BuildMI that's adding
%FP without a define flag. Usually you put the destination register
inside the call to BuildMI, and inputs with "addReg(...)" and so on.
All this actually does is fiddle the flags in an appropriate manner;
you can emulate it with addReg, but why bother? So what you should be
looking for is something like:

BuildMI(LDri_ab).addReg(Dest).addReg(Src).addImm(Offset)

and changing it to:

BuildMI(LDri_ab, Dest).addReg(Src).addImm(Offset)

Hope this helps.

Tim.

Tim,

Thank you very much, that did indeed fix things. I believe the word I should be saying is: ‘oops’!

Stephen