diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h --- a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h @@ -144,6 +144,13 @@ MachineInstr *getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI); +/// Find the source register for \p Reg, folding away any trivial copies. It +/// will be an output register of the instruction that getDefIgnoringCopies +/// returns. May return an invalid register if \p Reg is not a generic virtual +/// register. +Register getSrcRegIgnoringCopies(Register Reg, + const MachineRegisterInfo &MRI); + /// Returns an APFloat from Val converted to the appropriate size. APFloat getAPFloatFromSize(double Val, unsigned Size); diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp --- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp +++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp @@ -300,20 +300,33 @@ return MI->getOperand(1).getFPImm(); } -llvm::MachineInstr *llvm::getDefIgnoringCopies(Register Reg, - const MachineRegisterInfo &MRI) { +static std::pair getDefSrcRegIgnoringCopies( + Register Reg, + const MachineRegisterInfo &MRI) { + Register DefSrcReg = Reg; auto *DefMI = MRI.getVRegDef(Reg); auto DstTy = MRI.getType(DefMI->getOperand(0).getReg()); if (!DstTy.isValid()) - return nullptr; + return std::pair(nullptr, Register()); while (DefMI->getOpcode() == TargetOpcode::COPY) { Register SrcReg = DefMI->getOperand(1).getReg(); auto SrcTy = MRI.getType(SrcReg); if (!SrcTy.isValid() || SrcTy != DstTy) break; DefMI = MRI.getVRegDef(SrcReg); + DefSrcReg = SrcReg; } - return DefMI; + return std::make_pair(DefMI, DefSrcReg); +} + +Register llvm::getSrcRegIgnoringCopies(Register Reg, + const MachineRegisterInfo &MRI) { + return getDefSrcRegIgnoringCopies(Reg, MRI).second; +} + +llvm::MachineInstr *llvm::getDefIgnoringCopies(Register Reg, + const MachineRegisterInfo &MRI) { + return getDefSrcRegIgnoringCopies(Reg, MRI).first; } llvm::MachineInstr *llvm::getOpcodeDef(unsigned Opcode, Register Reg, diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -1575,10 +1575,9 @@ // G_STORE %x:gpr(s32) // // And then continue the selection process normally. - MachineInstr *Def = getDefIgnoringCopies(I.getOperand(0).getReg(), MRI); - if (!Def) + Register DefDstReg = getSrcRegIgnoringCopies(I.getOperand(0).getReg(), MRI); + if (!DefDstReg.isValid()) return false; - Register DefDstReg = Def->getOperand(0).getReg(); LLT DefDstTy = MRI.getType(DefDstReg); Register StoreSrcReg = I.getOperand(0).getReg(); LLT StoreSrcTy = MRI.getType(StoreSrcReg);