diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h --- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h @@ -409,10 +409,13 @@ /// Returns the original SrcReg unless it is the target of a copy-like /// operation, in which case we chain backwards through all such operations - /// to the ultimate source register. If a physical register is encountered, + /// to the ultimate source register. If a physical register is encountered, /// we stop the search. + /// If one definition in the copy chain has multiple uses, set \p + /// AllDefHaveOneUser to false, otherwise set it to true. virtual Register lookThruCopyLike(Register SrcReg, - const MachineRegisterInfo *MRI) const; + const MachineRegisterInfo *MRI, + bool *AllDefHaveOneUser = nullptr) const; /// Return a null-terminated list of all of the callee-saved registers on /// this target. The register should be in the order of desired callee-save diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp --- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp +++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp @@ -511,11 +511,18 @@ Register TargetRegisterInfo::lookThruCopyLike(Register SrcReg, - const MachineRegisterInfo *MRI) const { + const MachineRegisterInfo *MRI, + bool *AllDefHaveOneUser) const { + if (AllDefHaveOneUser) + *AllDefHaveOneUser = true; + while (true) { const MachineInstr *MI = MRI->getVRegDef(SrcReg); - if (!MI->isCopyLike()) + if (!MI->isCopyLike()) { + if (AllDefHaveOneUser && !MRI->hasOneNonDBGUse(SrcReg)) + *AllDefHaveOneUser = false; return SrcReg; + } Register CopySrcReg; if (MI->isCopy()) @@ -525,8 +532,11 @@ CopySrcReg = MI->getOperand(2).getReg(); } - if (!CopySrcReg.isVirtual()) + if (!CopySrcReg.isVirtual()) { + if (AllDefHaveOneUser) + *AllDefHaveOneUser = false; return CopySrcReg; + } SrcReg = CopySrcReg; }