Index: lib/CodeGen/MachineVerifier.cpp =================================================================== --- lib/CodeGen/MachineVerifier.cpp +++ lib/CodeGen/MachineVerifier.cpp @@ -1713,6 +1713,34 @@ LaneBitmask Mask = 0; LaneBitmask MaxMask = MRI->getMaxLaneMaskForVReg(Reg); + // If the LiveInterval has subregister information we want to check that + // for each definition that defines the whole register every subrange has at + // least + // a dead definition for it. + if (LI.hasSubRanges()) { + for (auto DI = MRI->def_begin(Reg), DE = MRI->def_end(); + DI != DE; ++DI) { + MachineOperand &MO = *DI; + // We are defining the whole register, so all the subranges should have + // at least a dead definition. + if (MO.getSubReg() == 0) { + LaneBitmask LiveMask = 0; + for (const LiveInterval::SubRange &SR : LI.subranges()) { + SlotIndex DefSlot = + LiveInts->getInstructionIndex(MO.getParent()).getRegSlot(); + if (SR.liveAt(DefSlot)) + LiveMask |= SR.LaneMask; + } + // If any lane didn't have a proper definition report. + LaneBitmask MOMask = TRI->getSubRegIndexLaneMask(MO.getSubReg()) & MaxMask; + if ((LiveMask & MOMask) != MOMask) { + report("Lane mask defined but no sub range reports its definition", + MF); + } + } + } + } + for (const LiveInterval::SubRange &SR : LI.subranges()) { if ((Mask & SR.LaneMask) != 0) { report("Lane masks of sub ranges overlap in live interval", MF); Index: lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- lib/CodeGen/RegisterCoalescer.cpp +++ lib/CodeGen/RegisterCoalescer.cpp @@ -999,6 +999,37 @@ updateRegDefsUses(DstReg, DstReg, DstIdx); NewMI->getOperand(0).setSubReg(NewIdx); + // Add dead subregister definitions if we are defining the whole register + // but only part of it is live. + // This could happen if the rematerialization instruction is rematerializing + // more than actually is used in the register. + // An example would be: + // vreg1 = LOAD CONSTANTS 5, 8 ; Loading both 5 and 8 in different subregs + // ; Copying only part of the register here, but the rest is undef. + // vreg2:sub_16bit = COPY vreg1:sub_16bit + // ==> + // ; Materialize all the constants but only using one + // vreg2 = LOAD_CONSTANTS 5, 8 + // + // at this point for the part that wasn't defined before we could have + // subranges missing the definition. + LiveInterval &DstInt = LIS->getInterval(DstReg); + if (NewIdx == 0 && DstInt.hasSubRanges()) { + SlotIndex CurrIdx = LIS->getInstructionIndex(NewMI); + LaneBitmask MaxMask = MRI->getMaxLaneMaskForVReg(DstReg); + for (LiveInterval::SubRange &SR : DstInt.subranges()) { + if (!SR.liveAt(CurrIdx.getRegSlot())) + SR.createDeadDef(CurrIdx.getRegSlot(), LIS->getVNInfoAllocator()); + MaxMask &= ~SR.LaneMask; + } + if (MaxMask != 0) { + LiveInterval::SubRange *SR = + DstInt.createSubRange(LIS->getVNInfoAllocator(), MaxMask); + SR->createDeadDef(CurrIdx.getRegSlot(), LIS->getVNInfoAllocator()); + SlotIndex DefIndex = CurrIdx.getRegSlot(NewMI->getOperand(0).isEarlyClobber()); + SR->createDeadDef(DefIndex, LIS->getVNInfoAllocator()); + } + } } else if (NewMI->getOperand(0).getReg() != CopyDstReg) { // The New instruction may be defining a sub-register of what's actually // been asked for. If so it must implicitly define the whole thing.