- // 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 (MRI->subRegLivenessEnabled()) {
+ // When reading a partial undefined value we must not add a kill flag.
+ // The regalloc might have used the undef lane for something else.
+ // Example:
+ // %vreg1 = ... ; R32: %vreg1
+ // %vreg2:high16 = ... ; R64: %vreg2
+ // = read %vreg2<kill> ; R64: %vreg2
+ // = read %vreg1 ; R32: %vreg1
+ // The <kill> flag is correct for %vreg2, but the register allocator may
+ // assign R0L to %vreg1, and R0 to %vreg2 because the low 32bits of R0
+ // are actually never written by %vreg2. After assignment the <kill>
+ // flag at the read instruction is invalid.
+ LaneBitmask DefinedLanesMask;
+ if (!SRs.empty()) {
+ // Compute a mask of lanes that are defined.
+ DefinedLanesMask = 0;
+ for (auto &SRP : SRs) {
+ const LiveInterval::SubRange &SR = *SRP.first;
+ LiveRange::const_iterator &I = SRP.second;
+ if (I == SR.end())
+ continue;
+ I = SR.advanceTo(I, RI->end);
+ if (I == SR.end() || I->start >= RI->end)
+ continue;
+ // I is overlapping RI
+ DefinedLanesMask |= SR.LaneMask;
+ }
+ } else
+ DefinedLanesMask = ~0u;
+
+ bool IsFullWrite = false;
+ for (const MachineOperand &MO : MI->operands()) {
+ if (!MO.isReg() || MO.getReg() != Reg)
+ continue;
+ if (MO.isUse()) {
+ // Reading any undefined lanes?
+ LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(MO.getSubReg());
+ if ((UseMask & ~DefinedLanesMask) != 0)
+ goto CancelKill;
+ } else if (MO.getSubReg() == 0) {
+ // Writing to the full register?
+ assert(MO.isDef());
+ IsFullWrite = true;