VirtRegMap: No implicit defs/uses for super registers with subreg liveness tracking.
Adding the implicit defs/uses to the superregisters is semantically questionable
but was not dangerous before as the register allocator never assigned the same
register to two overlapping LiveIntervals even when the actually live
subregisters do not overlap. With subregister liveness tracking enabled this
does actually happen and leads to subsequent bugs if we don't stop adding
the superregister defs/uses.
llvm-svn: 223892
diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
index dde55f9..1e78259 100644
--- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -671,6 +671,30 @@
CancelKill = true;
break;
}
+
+ // If an instruction writes to a subregister, a new segment starts in the
+ // LiveInterval. In this case adding Kill-Flags is incorrect if no
+ // super registers defs/uses are appended to the instruction which is
+ // what we do when subregister liveness tracking is enabled.
+ if (MRI->tracksSubRegLiveness()) {
+ // Next segment has to be adjacent in the subregister write case.
+ LiveRange::iterator N = std::next(RI);
+ if (N != LI->end() && N->start == RI->end) {
+ // See if we have a partial write operand
+ bool IsFullWrite = false;
+ for (MachineInstr::const_mop_iterator MOp = MI->operands_begin(),
+ MOpE = MI->operands_end(); MOp != MOpE; ++MOp) {
+ if (MOp->isReg() && !MOp->isDef() && MOp->getReg() == Reg
+ && MOp->getSubReg() == 0) {
+ IsFullWrite = true;
+ break;
+ }
+ }
+ if (!IsFullWrite)
+ CancelKill = true;
+ }
+ }
+
if (CancelKill)
MI->clearRegisterKills(Reg, nullptr);
else