[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