Index: lib/CodeGen/TargetSchedule.cpp =================================================================== --- lib/CodeGen/TargetSchedule.cpp +++ lib/CodeGen/TargetSchedule.cpp @@ -232,6 +232,37 @@ return Latency; unsigned UseIdx = findUseIdx(UseMI, UseOperIdx); int Advance = STI->getReadAdvanceCycles(UseDesc, UseIdx, WriteID); + + // Take extra care with implicit ops that are not part of the instruction + // descriptor (typically those added by RegAlloc for the full register). + const MCInstrDesc *UseIDesc = &UseMI->getDesc(); + const MachineOperand &UseMO = UseMI->getOperand(UseOperIdx); + const TargetRegisterInfo *TRI = UseMI->getMF()->getSubtarget().getRegisterInfo(); + if (!Advance && UseMO.isImplicit() && + !UseIDesc->hasImplicitUseOfPhysReg(UseMO.getReg())) { + UseIdx = 0; + int SubAdv = INT_MAX; + for (unsigned MOIdx = 0; MOIdx < UseMI->getNumOperands(); MOIdx++) { + const MachineOperand &MO = UseMI->getOperand(MOIdx); + // Only consider operands part of UseDesc. + if (MOIdx >= UseIDesc->getNumOperands() && + ((MO.isDef() && !UseIDesc->hasImplicitDefOfPhysReg(MO.getReg())) || + (MO.isUse() && !UseIDesc->hasImplicitUseOfPhysReg(MO.getReg())))) + continue; + + // Get the smallest advance for any subregister of UseMO. + if (MO.isReg() && MO.readsReg() && !MO.isDef()) { + if (TRI->isSubRegister(UseMO.getReg(), MO.getReg())) + SubAdv = std::min(SubAdv, STI->getReadAdvanceCycles(UseDesc, UseIdx, WriteID)); + UseIdx++; + } + if (SubAdv == 0) + break; + } + if (SubAdv < INT_MAX && SubAdv != 0) + Advance = SubAdv; + } + if (Advance > 0 && (unsigned)Advance > Latency) // unsigned wrap return 0; return Latency - Advance;