diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h --- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h @@ -1278,7 +1278,8 @@ // Adding Use to ArtifactList. WrapperObserver.changedInstr(Use); break; - case TargetOpcode::COPY: { + case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: { Register Copy = Use.getOperand(0).getReg(); if (Copy.isVirtual()) UpdatedDefs.push_back(Copy); @@ -1299,6 +1300,7 @@ static Register getArtifactSrcReg(const MachineInstr &MI) { switch (MI.getOpcode()) { case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: case TargetOpcode::G_TRUNC: case TargetOpcode::G_ZEXT: case TargetOpcode::G_ANYEXT: @@ -1423,7 +1425,8 @@ using namespace llvm::MIPatternMatch; Register TmpReg; - while (mi_match(Reg, MRI, m_Copy(m_Reg(TmpReg)))) { + while (mi_match(Reg, MRI, m_Copy(m_Reg(TmpReg))) || + mi_match(Reg, MRI, m_Pred_Copy(m_Reg(TmpReg)))) { if (MRI.getType(TmpReg).isValid()) Reg = TmpReg; else diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h --- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h @@ -631,6 +631,12 @@ return UnaryOp_match(std::forward(Src)); } +template +inline UnaryOp_match m_Pred_Copy(SrcTy &&Src) { + return UnaryOp_match( + std::forward(Src)); +} + template inline UnaryOp_match m_GFSqrt(const SrcTy &Src) { return UnaryOp_match(Src); diff --git a/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h b/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h --- a/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h @@ -85,6 +85,7 @@ class raw_ostream; class TargetPassConfig; class TargetRegisterInfo; +class TargetInstrInfo; /// This pass implements the reg bank selector pass used in the GlobalISel /// pipeline. At the end of this pass, all register operands have been assigned @@ -493,6 +494,9 @@ /// Information on the register classes for the current function. const TargetRegisterInfo *TRI = nullptr; + /// Information used to access the description of the opcodes. + const TargetInstrInfo *TII = nullptr; + /// Get the frequency of blocks. /// This is required for non-fast mode. MachineBlockFrequencyInfo *MBFI = nullptr; diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -1342,7 +1342,8 @@ } bool isCopy() const { - return getOpcode() == TargetOpcode::COPY; + return getOpcode() == TargetOpcode::COPY || + getOpcode() == TargetOpcode::PRED_COPY; } bool isFullCopy() const { @@ -1376,6 +1377,7 @@ case TargetOpcode::PHI: case TargetOpcode::G_PHI: case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: case TargetOpcode::INSERT_SUBREG: case TargetOpcode::SUBREG_TO_REG: case TargetOpcode::REG_SEQUENCE: diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h --- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -98,10 +98,11 @@ class TargetInstrInfo : public MCInstrInfo { public: TargetInstrInfo(unsigned CFSetupOpcode = ~0u, unsigned CFDestroyOpcode = ~0u, - unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u) + unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u, + unsigned CopyOpcode = TargetOpcode::COPY) : CallFrameSetupOpcode(CFSetupOpcode), CallFrameDestroyOpcode(CFDestroyOpcode), CatchRetOpcode(CatchRetOpcode), - ReturnOpcode(ReturnOpcode) {} + ReturnOpcode(ReturnOpcode), CopyOpcode(CopyOpcode) {} TargetInstrInfo(const TargetInstrInfo &) = delete; TargetInstrInfo &operator=(const TargetInstrInfo &) = delete; virtual ~TargetInstrInfo(); @@ -240,6 +241,7 @@ unsigned getCatchReturnOpcode() const { return CatchRetOpcode; } unsigned getReturnOpcode() const { return ReturnOpcode; } + unsigned getCopyOpcode() const { return CopyOpcode; } /// Returns the actual stack pointer adjustment made by an instruction /// as part of a call sequence. By default, only call frame setup/destroy @@ -1944,7 +1946,7 @@ MachineInstr *buildCopy(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsPt, const DebugLoc &DL, Register Dst) const { - return BuildMI(MBB, InsPt, DL, get(TargetOpcode::COPY), Dst); + return BuildMI(MBB, InsPt, DL, get(getCopyOpcode()), Dst); } /// Helper function for inserting a COPY to \p Dst from \p Src at insertion @@ -1953,7 +1955,7 @@ MachineBasicBlock::iterator InsPt, const DebugLoc &DL, Register Dst, Register Src, unsigned Flags = 0, unsigned SubReg = 0) const { - return BuildMI(MBB, InsPt, DL, get(TargetOpcode::COPY), Dst) + return BuildMI(MBB, InsPt, DL, get(getCopyOpcode()), Dst) .addReg(Src, Flags, SubReg); } @@ -1966,7 +1968,7 @@ unsigned SubReg = 0) const { MachineFunction &MF = *MBB.getParent(); MachineInstr *MI = - MF.CreateMachineInstr(get(TargetOpcode::COPY), MIMD.getDL()); + MF.CreateMachineInstr(get(getCopyOpcode()), MIMD.getDL()); MBB.insert(InsPt, MI); return MachineInstrBuilder(MF, MI) .setPCSections(MIMD.getPCSections()) @@ -2133,6 +2135,7 @@ unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode; unsigned CatchRetOpcode; unsigned ReturnOpcode; + unsigned CopyOpcode; }; /// Provide DenseMapInfo for TargetInstrInfo::RegSubRegPair. diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -109,6 +109,10 @@ /// used to copy between subregisters of virtual registers. HANDLE_TARGET_OPCODE(COPY) +/// PRED_COPY - Target-independent register copy with a predication. +/// Some targets require it for special handling certain register copies. + HANDLE_TARGET_OPCODE(PRED_COPY) + /// BUNDLE - This instruction represents an instruction bundle. Instructions /// which immediately follow a BUNDLE instruction which are marked with /// 'InsideBundle' flag are inside the bundle. diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td --- a/llvm/include/llvm/Target/GlobalISel/Combine.td +++ b/llvm/include/llvm/Target/GlobalISel/Combine.td @@ -126,8 +126,8 @@ def unsigned_matchinfo: GIDefMatchData<"unsigned">; def copy_prop : GICombineRule< - (defs root:$d), - (match (COPY $d, $s):$mi, + (defs root:$mi), + (match (wip_match_opcode COPY, PRED_COPY):$mi, [{ return Helper.matchCombineCopy(*${mi}); }]), (apply [{ Helper.applyCombineCopy(*${mi}); }])>; diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -1261,6 +1261,15 @@ let isAsCheapAsAMove = true; let hasNoSchedulingInfo = false; } +def PRED_COPY : StandardPseudoInstruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src); + let AsmString = "PRED_COPY"; + let hasSideEffects = false; + let isAsCheapAsAMove = true; + let hasNoSchedulingInfo = false; + let isPredicable = true; +} def BUNDLE : StandardPseudoInstruction { let OutOperandList = (outs); let InOperandList = (ins variable_ops); diff --git a/llvm/lib/CodeGen/CodeGenCommonISel.cpp b/llvm/lib/CodeGen/CodeGenCommonISel.cpp --- a/llvm/lib/CodeGen/CodeGenCommonISel.cpp +++ b/llvm/lib/CodeGen/CodeGenCommonISel.cpp @@ -234,6 +234,7 @@ case TargetOpcode::G_TRUNC: return getSalvageOpsForTrunc(MRI, MI, Ops); case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: return getSalvageOpsForCopy(MRI, MI); default: return nullptr; diff --git a/llvm/lib/CodeGen/DetectDeadLanes.cpp b/llvm/lib/CodeGen/DetectDeadLanes.cpp --- a/llvm/lib/CodeGen/DetectDeadLanes.cpp +++ b/llvm/lib/CodeGen/DetectDeadLanes.cpp @@ -55,6 +55,7 @@ // are not lowered to a COPY. switch (MI.getOpcode()) { case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: case TargetOpcode::PHI: case TargetOpcode::INSERT_SUBREG: case TargetOpcode::REG_SEQUENCE: @@ -151,6 +152,7 @@ switch (MI.getOpcode()) { case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: case TargetOpcode::PHI: return UsedLanes; case TargetOpcode::REG_SEQUENCE: { @@ -253,6 +255,7 @@ break; } case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: case TargetOpcode::PHI: break; default: diff --git a/llvm/lib/CodeGen/ExpandPostRAPseudos.cpp b/llvm/lib/CodeGen/ExpandPostRAPseudos.cpp --- a/llvm/lib/CodeGen/ExpandPostRAPseudos.cpp +++ b/llvm/lib/CodeGen/ExpandPostRAPseudos.cpp @@ -211,6 +211,7 @@ MadeChange |= LowerSubregToReg(&MI); break; case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: MadeChange |= LowerCopy(&MI); break; case TargetOpcode::DBG_VALUE: diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -4303,7 +4303,7 @@ LLT LHSTy = MRI.getType(LHS); unsigned LHSSize = LHSTy.getSizeInBits(); unsigned DstSize = DstTy.getSizeInBits(); - unsigned Op = TargetOpcode::COPY; + unsigned Op = Builder.getTII().getCopyOpcode(); if (DstSize != LHSSize) Op = DstSize < LHSSize ? TargetOpcode::G_TRUNC : TargetOpcode::G_ZEXT; if (!isLegalOrBeforeLegalizer({Op, {DstTy, LHSTy}})) diff --git a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp --- a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp @@ -36,6 +36,7 @@ const MachineInstr *MI = MRI.getVRegDef(R); switch (MI->getOpcode()) { case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: return computeKnownAlignment(MI->getOperand(1).getReg(), Depth); case TargetOpcode::G_ASSERT_ALIGN: { // TODO: Min with source @@ -200,6 +201,7 @@ break; } case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: case TargetOpcode::G_PHI: case TargetOpcode::PHI: { Known.One = APInt::getAllOnes(BitWidth); @@ -631,7 +633,8 @@ unsigned FirstAnswer = 1; switch (Opcode) { - case TargetOpcode::COPY: { + case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: { MachineOperand &Src = MI.getOperand(1); if (Src.getReg().isVirtual() && Src.getSubReg() == 0 && MRI.getType(Src.getReg()).isValid()) { diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -7587,7 +7587,8 @@ return UnableToLegalize; // FIXME: handle extension. // This can be just a plain copy. Observer.changingInstr(MI); - MI.setDesc(MIRBuilder.getTII().get(TargetOpcode::COPY)); + const TargetInstrInfo &TII = MIRBuilder.getTII(); + MI.setDesc(TII.get(TII.getCopyOpcode())); Observer.changedInstr(MI); return Legalized; } diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -287,7 +287,7 @@ MachineInstrBuilder MachineIRBuilder::buildCopy(const DstOp &Res, const SrcOp &Op) { - return buildInstr(TargetOpcode::COPY, Res, Op); + return buildInstr(getTII().getCopyOpcode(), Res, Op); } MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res, @@ -511,7 +511,7 @@ assert(Res.getLLTTy(*getMRI()).isScalar() == Op.getLLTTy(*getMRI()).isScalar()); - unsigned Opcode = TargetOpcode::COPY; + unsigned Opcode = getTII().getCopyOpcode(); if (Res.getLLTTy(*getMRI()).getSizeInBits() > Op.getLLTTy(*getMRI()).getSizeInBits()) Opcode = ExtOpc; @@ -1138,6 +1138,7 @@ break; } case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: assert(DstOps.size() == 1 && "Invalid Dst"); // If the caller wants to add a subreg source it has to be done separately // so we may not have any SrcOps at this point yet. diff --git a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp --- a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp @@ -25,6 +25,7 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterBank.h" #include "llvm/CodeGen/RegisterBankInfo.h" +#include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/CodeGen/TargetRegisterInfo.h" @@ -83,6 +84,7 @@ assert(RBI && "Cannot work without RegisterBankInfo"); MRI = &MF.getRegInfo(); TRI = MF.getSubtarget().getRegisterInfo(); + TII = MF.getSubtarget().getInstrInfo(); TPC = &getAnalysis(); if (OptMode != Mode::Fast) { MBFI = &getAnalysis(); @@ -159,9 +161,9 @@ // Build the instruction used to repair, then clone it at the right // places. Avoiding buildCopy bypasses the check that Src and Dst have the // same types because the type is a placeholder when this function is called. - MI = MIRBuilder.buildInstrNoInsert(TargetOpcode::COPY) - .addDef(Dst) - .addUse(Src); + MI = MIRBuilder.buildInstrNoInsert(TII->getCopyOpcode()) + .addDef(Dst) + .addUse(Src); LLVM_DEBUG(dbgs() << "Copy: " << printReg(Src) << ':' << printRegClassOrBank(Src, *MRI, TRI) << " to: " << printReg(Dst) << ':' 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 @@ -329,6 +329,7 @@ VReg = MI->getOperand(1).getReg(); break; case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: VReg = MI->getOperand(1).getReg(); if (VReg.isPhysical()) return std::nullopt; diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -1833,7 +1833,8 @@ // Verify properties of various specific instruction types switch (MI->getOpcode()) { - case TargetOpcode::COPY: { + case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: { const MachineOperand &DstOp = MI->getOperand(0); const MachineOperand &SrcOp = MI->getOperand(1); const Register SrcReg = SrcOp.getReg(); diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp --- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp +++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp @@ -1022,7 +1022,7 @@ // Get rid of the sub-register index. CopyLike.removeOperand(2); // Morph the operation into a COPY. - CopyLike.setDesc(TII.get(TargetOpcode::COPY)); + CopyLike.setDesc(TII.get(TII.getCopyOpcode())); return true; } CopyLike.getOperand(CurrentSrcIdx + 1).setImm(NewSubReg); @@ -1110,6 +1110,7 @@ default: return nullptr; case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: return new CopyRewriter(MI); case TargetOpcode::INSERT_SUBREG: return new InsertSubregRewriter(MI); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2232,7 +2232,7 @@ // TODO: We don't have FREEZE pseudo-instruction in MachineInstr-level now. // If FREEZE instruction is added later, the code below must be changed as // well. - CurDAG->SelectNodeTo(N, TargetOpcode::COPY, N->getValueType(0), + CurDAG->SelectNodeTo(N, TII->getCopyOpcode(), N->getValueType(0), N->getOperand(0)); } diff --git a/llvm/lib/CodeGen/SplitKit.cpp b/llvm/lib/CodeGen/SplitKit.cpp --- a/llvm/lib/CodeGen/SplitKit.cpp +++ b/llvm/lib/CodeGen/SplitKit.cpp @@ -517,7 +517,7 @@ SlotIndex SplitEditor::buildSingleSubRegCopy(Register FromReg, Register ToReg, MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, unsigned SubIdx, LiveInterval &DestLI, bool Late, SlotIndex Def) { - const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY); + const MCInstrDesc &Desc = TII.get(TII.getCopyOpcode()); bool FirstCopy = !Def.isValid(); MachineInstr *CopyMI = BuildMI(MBB, InsertBefore, DebugLoc(), Desc) .addReg(ToReg, RegState::Define | getUndefRegState(FirstCopy) diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1837,7 +1837,7 @@ mi->getOperand(0).setSubReg(SubIdx); mi->getOperand(0).setIsUndef(mi->getOperand(1).isUndef()); mi->removeOperand(1); - mi->setDesc(TII->get(TargetOpcode::COPY)); + mi->setDesc(TII->get(TII->getCopyOpcode())); LLVM_DEBUG(dbgs() << "\t\tconvert to:\t" << *mi); // Update LiveIntervals. @@ -1925,7 +1925,7 @@ // Insert the sub-register copy. MachineInstr *CopyMI = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), - TII->get(TargetOpcode::COPY)) + TII->get(TII->getCopyOpcode())) .addReg(DstReg, RegState::Define, SubIdx) .add(UseMO); diff --git a/llvm/lib/CodeGen/VLIWMachineScheduler.cpp b/llvm/lib/CodeGen/VLIWMachineScheduler.cpp --- a/llvm/lib/CodeGen/VLIWMachineScheduler.cpp +++ b/llvm/lib/CodeGen/VLIWMachineScheduler.cpp @@ -122,6 +122,7 @@ case TargetOpcode::REG_SEQUENCE: case TargetOpcode::IMPLICIT_DEF: case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: case TargetOpcode::INLINEASM: case TargetOpcode::INLINEASM_BR: break; @@ -172,6 +173,7 @@ case TargetOpcode::CFI_INSTRUCTION: case TargetOpcode::EH_LABEL: case TargetOpcode::COPY: + case TargetOpcode::PRED_COPY: case TargetOpcode::INLINEASM: case TargetOpcode::INLINEASM_BR: break; diff --git a/llvm/lib/Target/AArch64/AArch64SchedA53.td b/llvm/lib/Target/AArch64/AArch64SchedA53.td --- a/llvm/lib/Target/AArch64/AArch64SchedA53.td +++ b/llvm/lib/Target/AArch64/AArch64SchedA53.td @@ -205,6 +205,7 @@ // Miscellaneous //--- def : InstRW<[WriteI], (instrs COPY)>; +def : InstRW<[WriteI], (instrs PRED_COPY)>; //--- // Vector Loads diff --git a/llvm/lib/Target/AArch64/AArch64SchedA55.td b/llvm/lib/Target/AArch64/AArch64SchedA55.td --- a/llvm/lib/Target/AArch64/AArch64SchedA55.td +++ b/llvm/lib/Target/AArch64/AArch64SchedA55.td @@ -270,6 +270,7 @@ def : InstRW<[WriteAdr, CortexA55WriteVLD1,CortexA55WriteLDP2], (instregex "LDP(X|D)(pre|post)")>; def : InstRW<[WriteAdr, CortexA55WriteVLD1,CortexA55WriteLDP4], (instregex "LDPQ(pre|post)")>; def : InstRW<[WriteI], (instrs COPY)>; +def : InstRW<[WriteI], (instrs PRED_COPY)>; //--- // Vector Loads - 64-bit per cycle //--- diff --git a/llvm/lib/Target/AArch64/AArch64SchedA57.td b/llvm/lib/Target/AArch64/AArch64SchedA57.td --- a/llvm/lib/Target/AArch64/AArch64SchedA57.td +++ b/llvm/lib/Target/AArch64/AArch64SchedA57.td @@ -132,6 +132,7 @@ // ----------------------------------------------------------------------------- def : InstRW<[WriteI], (instrs COPY)>; +def : InstRW<[WriteI], (instrs PRED_COPY)>; // Branch Instructions diff --git a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td --- a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td +++ b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td @@ -613,6 +613,7 @@ "CSNEG(W|X)r")>; def : InstRW<[WriteI], (instrs COPY)>; +def : InstRW<[WriteI], (instrs PRED_COPY)>; // ALU, extend and/or shift def : WriteRes { diff --git a/llvm/lib/Target/AArch64/AArch64SchedAmpere1.td b/llvm/lib/Target/AArch64/AArch64SchedAmpere1.td --- a/llvm/lib/Target/AArch64/AArch64SchedAmpere1.td +++ b/llvm/lib/Target/AArch64/AArch64SchedAmpere1.td @@ -687,6 +687,7 @@ // Specialising the scheduling model further for Ampere-1. def : InstRW<[Ampere1Write_1cyc_1AB], (instrs COPY)>; +def : InstRW<[Ampere1Write_1cyc_1AB], (instrs PRED_COPY)>; // Branch instructions def : InstRW<[Ampere1Write_1cyc_1A], (instrs Bcc, BL, RET)>; diff --git a/llvm/lib/Target/AArch64/AArch64SchedCyclone.td b/llvm/lib/Target/AArch64/AArch64SchedCyclone.td --- a/llvm/lib/Target/AArch64/AArch64SchedCyclone.td +++ b/llvm/lib/Target/AArch64/AArch64SchedCyclone.td @@ -127,7 +127,7 @@ SchedVar, SchedVar, SchedVar]>; -def : InstRW<[WriteMov], (instrs COPY,ORRXrr,ADDXrr)>; +def : InstRW<[WriteMov], (instrs COPY,PRED_COPY,ORRXrr,ADDXrr)>; // Move non-zero immediate is an integer ALU op. // MOVN,MOVZ,MOVK diff --git a/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td b/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td --- a/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td +++ b/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td @@ -507,6 +507,7 @@ // Move instructions. def : InstRW<[M3WriteCOPY], (instrs COPY)>; +def : InstRW<[M3WriteCOPY], (instrs PRED_COPY)>; def : InstRW<[M3WriteZ0], (instrs ADR, ADRP)>; def : InstRW<[M3WriteZ0], (instregex "^MOV[NZ][WX]i")>; diff --git a/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td b/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td --- a/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td +++ b/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td @@ -604,6 +604,7 @@ // Move instructions. def : InstRW<[M4WriteCOPY], (instrs COPY)>; +def : InstRW<[M4WriteCOPY], (instrs PRED_COPY)>; def : InstRW<[M4WriteZ0], (instrs ADR, ADRP)>; def : InstRW<[M4WriteZ0], (instregex "^MOV[NZ][WX]i")>; diff --git a/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td b/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td --- a/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td +++ b/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td @@ -651,6 +651,7 @@ // Move instructions. def : InstRW<[M5WriteCOPY], (instrs COPY)>; +def : InstRW<[M5WriteCOPY], (instrs PRED_COPY)>; def : InstRW<[M5WriteZ0], (instrs ADR, ADRP)>; def : InstRW<[M5WriteZ0], (instregex "^MOV[NZ][WX]i$")>; diff --git a/llvm/lib/Target/AArch64/AArch64SchedFalkorDetails.td b/llvm/lib/Target/AArch64/AArch64SchedFalkorDetails.td --- a/llvm/lib/Target/AArch64/AArch64SchedFalkorDetails.td +++ b/llvm/lib/Target/AArch64/AArch64SchedFalkorDetails.td @@ -580,6 +580,7 @@ // FIXME: This could be better modeled by looking at the regclasses of the operands. def : InstRW<[FalkorWr_1XYZ_1cyc], (instrs COPY)>; +def : InstRW<[FalkorWr_1XYZ_1cyc], (instrs PRED_COPY)>; // SIMD Floating-point Instructions // ----------------------------------------------------------------------------- diff --git a/llvm/lib/Target/AArch64/AArch64SchedKryo.td b/llvm/lib/Target/AArch64/AArch64SchedKryo.td --- a/llvm/lib/Target/AArch64/AArch64SchedKryo.td +++ b/llvm/lib/Target/AArch64/AArch64SchedKryo.td @@ -131,6 +131,7 @@ // ----------------------------------------------------------------------------- def : InstRW<[WriteI], (instrs COPY)>; +def : InstRW<[WriteI], (instrs PRED_COPY)>; // Detailed Refinedments diff --git a/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td b/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td --- a/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td +++ b/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td @@ -613,6 +613,7 @@ // ----------------------------------------------------------------------------- def : InstRW<[WriteI], (instrs COPY)>; +def : InstRW<[WriteI], (instrs PRED_COPY)>; // Branch Instructions // ----------------------------------------------------------------------------- diff --git a/llvm/lib/Target/AArch64/AArch64SchedTSV110.td b/llvm/lib/Target/AArch64/AArch64SchedTSV110.td --- a/llvm/lib/Target/AArch64/AArch64SchedTSV110.td +++ b/llvm/lib/Target/AArch64/AArch64SchedTSV110.td @@ -122,6 +122,7 @@ def : ReadAdvance; def : InstRW<[WriteI], (instrs COPY)>; +def : InstRW<[WriteI], (instrs PRED_COPY)>; // Detailed Refinements //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AArch64SchedThunderX.td b/llvm/lib/Target/AArch64/AArch64SchedThunderX.td --- a/llvm/lib/Target/AArch64/AArch64SchedThunderX.td +++ b/llvm/lib/Target/AArch64/AArch64SchedThunderX.td @@ -266,6 +266,7 @@ // Miscellaneous //--- def : InstRW<[WriteI], (instrs COPY)>; +def : InstRW<[WriteI], (instrs PRED_COPY)>; //--- // Vector Loads diff --git a/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td b/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td --- a/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td +++ b/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td @@ -436,6 +436,7 @@ "CSNEG(W|X)r")>; def : InstRW<[WriteI], (instrs COPY)>; +def : InstRW<[WriteI], (instrs PRED_COPY)>; // ALU, extend and/or shift def : WriteRes { diff --git a/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td b/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td --- a/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td +++ b/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td @@ -696,6 +696,7 @@ "CSNEG(W|X)r")>; def : InstRW<[WriteI], (instrs COPY)>; +def : InstRW<[WriteI], (instrs PRED_COPY)>; // ALU, extend and/or shift def : WriteRes { diff --git a/llvm/lib/Target/AMDGPU/SISchedule.td b/llvm/lib/Target/AMDGPU/SISchedule.td --- a/llvm/lib/Target/AMDGPU/SISchedule.td +++ b/llvm/lib/Target/AMDGPU/SISchedule.td @@ -200,6 +200,7 @@ } // End RetireOOO = 1 def : InstRW<[WriteCopy], (instrs COPY)>; +def : InstRW<[WriteCopy], (instrs PRED_COPY)>; } // End SchedModel = SIFullSpeedModel @@ -218,6 +219,7 @@ } // End RetireOOO = 1 def : InstRW<[WriteCopy], (instrs COPY)>; +def : InstRW<[WriteCopy], (instrs PRED_COPY)>; def : InstRW<[Write64Bit, MIReadVGPR], (instregex "^V_ACCVGPR_WRITE_B32_e64$")>; def : InstRW<[Write2PassMAI, MIMFMARead], (instregex "^V_MFMA_..._4X4X")>; def : InstRW<[Write8PassMAI, MIMFMARead], (instregex "^V_MFMA_..._16X16X")>; @@ -240,6 +242,7 @@ } // End RetireOOO = 1 def : InstRW<[WriteCopy], (instrs COPY)>; +def : InstRW<[WriteCopy], (instrs PRED_COPY)>; def : InstRW<[Write64Bit], (instregex "^V_ACCVGPR_WRITE_B32_e64$")>; def : InstRW<[Write2PassMAI, MIMFMARead], (instregex "^V_MFMA_.32_4X4X")>; def : InstRW<[Write8PassMAI, MIMFMARead], (instregex "^V_MFMA_.32_16X16X")>; @@ -262,6 +265,7 @@ def : HWVALUWriteRes; def : InstRW<[WriteCopy], (instrs COPY)>; +def : InstRW<[WriteCopy], (instrs PRED_COPY)>; def : InstRW<[Write64Bit], (instregex "^V_ACCVGPR_WRITE_B32_e64$")>; def : InstRW<[Write2PassMAI, MIMFMARead], (instregex "^V_MFMA_.32_4X4X")>; @@ -310,6 +314,7 @@ } // End RetireOOO = 1 def : InstRW<[WriteCopy], (instrs COPY)>; +def : InstRW<[WriteCopy], (instrs PRED_COPY)>; } // End SchedModel = GFX10SpeedModel @@ -336,5 +341,6 @@ def : HWWriteRes; def : InstRW<[WriteCopy], (instrs COPY)>; +def : InstRW<[WriteCopy], (instrs PRED_COPY)>; } // End SchedModel = GFX11SpeedModel diff --git a/llvm/lib/Target/AMDGPU/VOP3Instructions.td b/llvm/lib/Target/AMDGPU/VOP3Instructions.td --- a/llvm/lib/Target/AMDGPU/VOP3Instructions.td +++ b/llvm/lib/Target/AMDGPU/VOP3Instructions.td @@ -478,7 +478,8 @@ let GISelPredicateCode = [{ int64_t Imm = 0; if (!mi_match(MI.getOperand(2).getReg(), MRI, m_ICst(Imm)) && - !mi_match(MI.getOperand(2).getReg(), MRI, m_Copy(m_ICst(Imm)))) + !mi_match(MI.getOperand(2).getReg(), MRI, m_Copy(m_ICst(Imm))) && + !mi_match(MI.getOperand(2).getReg(), MRI, m_Pred_Copy(m_ICst(Imm)))) return false; return (uint64_t)Imm <= 4; }]; diff --git a/llvm/lib/Target/ARM/ARMScheduleA57.td b/llvm/lib/Target/ARM/ARMScheduleA57.td --- a/llvm/lib/Target/ARM/ARMScheduleA57.td +++ b/llvm/lib/Target/ARM/ARMScheduleA57.td @@ -151,6 +151,7 @@ // ----------------------------------------------------------------------------- def : InstRW<[A57Write_1cyc_1I], (instrs COPY)>; +def : InstRW<[A57Write_1cyc_1I], (instrs PRED_COPY)>; // --- 3.2 Branch Instructions --- // B, BX, BL, BLX (imm, reg != LR, reg == LR), CBZ, CBNZ diff --git a/llvm/lib/Target/ARM/ARMScheduleM4.td b/llvm/lib/Target/ARM/ARMScheduleM4.td --- a/llvm/lib/Target/ARM/ARMScheduleM4.td +++ b/llvm/lib/Target/ARM/ARMScheduleM4.td @@ -82,6 +82,7 @@ def : M4UnitL1; def : M4UnitL1I<(instregex "(t|t2)MOV")>; def : M4UnitL1I<(instrs COPY)>; +def : M4UnitL1I<(instrs PRED_COPY)>; def : M4UnitL1I<(instregex "t2IT", "t2MSR", "t2MRS")>; def : M4UnitL1I<(instregex "t2CLREX")>; def : M4UnitL1I<(instregex "t2SEL", "t2USAD8", "t2SML[AS]", diff --git a/llvm/lib/Target/ARM/ARMScheduleR52.td b/llvm/lib/Target/ARM/ARMScheduleR52.td --- a/llvm/lib/Target/ARM/ARMScheduleR52.td +++ b/llvm/lib/Target/ARM/ARMScheduleR52.td @@ -210,6 +210,7 @@ // Subtarget-specific overrides. Map opcodes to list of SchedReadWrites types. // def : InstRW<[WriteALU], (instrs COPY)>; +def : InstRW<[WriteALU], (instrs PRED_COPY)>; def : InstRW<[R52WriteALU_EX2, R52Read_EX1, R52Read_ISS], (instregex "SXTB", "SXTH", "SXTB16", "UXTB", "UXTH", "UXTB16", diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -51,6 +51,7 @@ SRLV, SSNOP, SUB, SUBu, WSBH, XOR, XORi)>; def : InstRW<[GenericWriteALU], (instrs COPY)>; +def : InstRW<[GenericWriteALU], (instrs PRED_COPY)>; // MIPSR6 // ====== diff --git a/llvm/lib/Target/Mips/MipsScheduleP5600.td b/llvm/lib/Target/Mips/MipsScheduleP5600.td --- a/llvm/lib/Target/Mips/MipsScheduleP5600.td +++ b/llvm/lib/Target/Mips/MipsScheduleP5600.td @@ -223,7 +223,7 @@ // xori def : InstRW<[P5600WriteEitherALU], (instrs ADD, ADDi, ADDiu, ANDi, ORi, ROTR, SEB, SEH, SLT, SLTu, SLL, SRA, SRL, XORi, - ADDu, SLLV, SRAV, SRLV, LSA, COPY)>; + ADDu, SLLV, SRAV, SRLV, LSA, COPY, PRED_COPY)>; // FPU Pipelines // ============= diff --git a/llvm/lib/Target/PowerPC/P10InstrResources.td b/llvm/lib/Target/PowerPC/P10InstrResources.td --- a/llvm/lib/Target/PowerPC/P10InstrResources.td +++ b/llvm/lib/Target/PowerPC/P10InstrResources.td @@ -1013,7 +1013,7 @@ NAND8_rec, NAND_rec, NOR, NOR8, NOR8_rec, NOR_rec, - COPY, OR, OR8, + COPY, PRED_COPY, OR, OR8, OR8_rec, OR_rec, ORC, ORC8, ORC8_rec, ORC_rec, diff --git a/llvm/lib/Target/PowerPC/P9InstrResources.td b/llvm/lib/Target/PowerPC/P9InstrResources.td --- a/llvm/lib/Target/PowerPC/P9InstrResources.td +++ b/llvm/lib/Target/PowerPC/P9InstrResources.td @@ -153,6 +153,7 @@ (instregex "ADDI(S)?toc(HA|L)(8)?$"), (instregex "LA(8)?$"), COPY, + PRED_COPY, MCRF, MCRXRX, XSNABSDP, diff --git a/llvm/lib/Target/RISCV/RISCVSchedRocket.td b/llvm/lib/Target/RISCV/RISCVSchedRocket.td --- a/llvm/lib/Target/RISCV/RISCVSchedRocket.td +++ b/llvm/lib/Target/RISCV/RISCVSchedRocket.td @@ -174,6 +174,7 @@ def : WriteRes; def : InstRW<[WriteIALU], (instrs COPY)>; +def : InstRW<[WriteIALU], (instrs PRED_COPY)>; //===----------------------------------------------------------------------===// // Bypass and advance diff --git a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td --- a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td +++ b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td @@ -167,6 +167,7 @@ def : WriteRes; def : InstRW<[WriteIALU], (instrs COPY)>; +def : InstRW<[WriteIALU], (instrs PRED_COPY)>; //===----------------------------------------------------------------------===// // Bypass and advance diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td @@ -189,6 +189,7 @@ // Pseudo -> reg move def : InstRW<[WLat1, FXa, NormalGr], (instregex "COPY(_TO_REGCLASS)?$")>; +def : InstRW<[WLat1, FXa, NormalGr], (instregex "PRED_COPY$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "EXTRACT_SUBREG$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "INSERT_SUBREG$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "REG_SEQUENCE$")>; diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ14.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ14.td --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ14.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ14.td @@ -190,6 +190,7 @@ // Pseudo -> reg move def : InstRW<[WLat1, FXa, NormalGr], (instregex "COPY(_TO_REGCLASS)?$")>; +def : InstRW<[WLat1, FXa, NormalGr], (instregex "PRED_COPY$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "EXTRACT_SUBREG$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "INSERT_SUBREG$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "REG_SEQUENCE$")>; diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ15.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ15.td --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ15.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ15.td @@ -191,6 +191,7 @@ // Pseudo -> reg move def : InstRW<[WLat1, FXa, NormalGr], (instregex "COPY(_TO_REGCLASS)?$")>; +def : InstRW<[WLat1, FXa, NormalGr], (instregex "PRED_COPY$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "EXTRACT_SUBREG$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "INSERT_SUBREG$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "REG_SEQUENCE$")>; diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ16.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ16.td --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ16.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ16.td @@ -191,6 +191,7 @@ // Pseudo -> reg move def : InstRW<[WLat1, FXa, NormalGr], (instregex "COPY(_TO_REGCLASS)?$")>; +def : InstRW<[WLat1, FXa, NormalGr], (instregex "PRED_COPY$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "EXTRACT_SUBREG$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "INSERT_SUBREG$")>; def : InstRW<[WLat1, FXa, NormalGr], (instregex "REG_SEQUENCE$")>; diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td @@ -168,6 +168,7 @@ // Pseudo -> reg move def : InstRW<[WLat1, FXU, NormalGr], (instregex "COPY(_TO_REGCLASS)?$")>; +def : InstRW<[WLat1, FXU, NormalGr], (instregex "PRED_COPY$")>; def : InstRW<[WLat1, FXU, NormalGr], (instregex "EXTRACT_SUBREG$")>; def : InstRW<[WLat1, FXU, NormalGr], (instregex "INSERT_SUBREG$")>; def : InstRW<[WLat1, FXU, NormalGr], (instregex "REG_SEQUENCE$")>; diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td --- a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td @@ -173,6 +173,7 @@ // Pseudo -> reg move def : InstRW<[WLat1, FXU, NormalGr], (instregex "COPY(_TO_REGCLASS)?$")>; +def : InstRW<[WLat1, FXU, NormalGr], (instregex "PRED_COPY$")>; def : InstRW<[WLat1, FXU, NormalGr], (instregex "EXTRACT_SUBREG$")>; def : InstRW<[WLat1, FXU, NormalGr], (instregex "INSERT_SUBREG$")>; def : InstRW<[WLat1, FXU, NormalGr], (instregex "REG_SEQUENCE$")>; diff --git a/llvm/lib/Target/X86/X86SchedBroadwell.td b/llvm/lib/Target/X86/X86SchedBroadwell.td --- a/llvm/lib/Target/X86/X86SchedBroadwell.td +++ b/llvm/lib/Target/X86/X86SchedBroadwell.td @@ -122,6 +122,7 @@ // Treat misc copies as a move. def : InstRW<[WriteMove], (instrs COPY)>; +def : InstRW<[WriteMove], (instrs PRED_COPY)>; // Idioms that clear a register, like xorps %xmm0, %xmm0. // These can often bypass execution ports completely. diff --git a/llvm/lib/Target/X86/X86SchedSandyBridge.td b/llvm/lib/Target/X86/X86SchedSandyBridge.td --- a/llvm/lib/Target/X86/X86SchedSandyBridge.td +++ b/llvm/lib/Target/X86/X86SchedSandyBridge.td @@ -114,6 +114,7 @@ // Treat misc copies as a move. def : InstRW<[WriteMove], (instrs COPY)>; +def : InstRW<[WriteMove], (instrs PRED_COPY)>; // Idioms that clear a register, like xorps %xmm0, %xmm0. // These can often bypass execution ports completely. diff --git a/llvm/lib/Target/X86/X86ScheduleAtom.td b/llvm/lib/Target/X86/X86ScheduleAtom.td --- a/llvm/lib/Target/X86/X86ScheduleAtom.td +++ b/llvm/lib/Target/X86/X86ScheduleAtom.td @@ -176,6 +176,7 @@ // Treat misc copies as a move. def : InstRW<[WriteMove], (instrs COPY)>; +def : InstRW<[WriteMove], (instrs PRED_COPY)>; //////////////////////////////////////////////////////////////////////////////// // Idioms that clear a register, like xorps %xmm0, %xmm0. diff --git a/llvm/lib/Target/X86/X86ScheduleBdVer2.td b/llvm/lib/Target/X86/X86ScheduleBdVer2.td --- a/llvm/lib/Target/X86/X86ScheduleBdVer2.td +++ b/llvm/lib/Target/X86/X86ScheduleBdVer2.td @@ -278,6 +278,7 @@ // Treat misc copies as a move. def : InstRW<[WriteMove], (instrs COPY)>; +def : InstRW<[WriteMove], (instrs PRED_COPY)>; //////////////////////////////////////////////////////////////////////////////// // Idioms that clear a register, like xorps %xmm0, %xmm0. diff --git a/llvm/lib/Target/X86/X86ScheduleSLM.td b/llvm/lib/Target/X86/X86ScheduleSLM.td --- a/llvm/lib/Target/X86/X86ScheduleSLM.td +++ b/llvm/lib/Target/X86/X86ScheduleSLM.td @@ -96,6 +96,7 @@ // Treat misc copies as a move. def : InstRW<[WriteMove], (instrs COPY)>; +def : InstRW<[WriteMove], (instrs PRED_COPY)>; defm : SLMWriteResPair; defm : SLMWriteResPair; diff --git a/llvm/lib/Target/X86/X86ScheduleZnver1.td b/llvm/lib/Target/X86/X86ScheduleZnver1.td --- a/llvm/lib/Target/X86/X86ScheduleZnver1.td +++ b/llvm/lib/Target/X86/X86ScheduleZnver1.td @@ -228,6 +228,7 @@ // Treat misc copies as a move. def : InstRW<[WriteMove], (instrs COPY)>; +def : InstRW<[WriteMove], (instrs PRED_COPY)>; // BMI1 BEXTR, BMI2 BZHI defm : ZnWriteResPair; diff --git a/llvm/lib/Target/X86/X86ScheduleZnver2.td b/llvm/lib/Target/X86/X86ScheduleZnver2.td --- a/llvm/lib/Target/X86/X86ScheduleZnver2.td +++ b/llvm/lib/Target/X86/X86ScheduleZnver2.td @@ -227,6 +227,7 @@ // Treat misc copies as a move. def : InstRW<[WriteMove], (instrs COPY)>; +def : InstRW<[WriteMove], (instrs PRED_COPY)>; // BMI1 BEXTR, BMI2 BZHI defm : Zn2WriteResPair; diff --git a/llvm/lib/Target/X86/X86ScheduleZnver3.td b/llvm/lib/Target/X86/X86ScheduleZnver3.td --- a/llvm/lib/Target/X86/X86ScheduleZnver3.td +++ b/llvm/lib/Target/X86/X86ScheduleZnver3.td @@ -512,6 +512,7 @@ // Treat misc copies as a move. def : InstRW<[WriteMove], (instrs COPY)>; +def : InstRW<[WriteMove], (instrs PRED_COPY)>; def Zn3WriteMOVBE16rm : SchedWriteRes<[Zn3AGU012, Zn3Load, Zn3ALU0123]> { let Latency = Znver3Model.LoadLatency; diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -1030,10 +1030,10 @@ OS << "struct " << ClassName << " : public TargetInstrInfo {\n" << " explicit " << ClassName << "(unsigned CFSetupOpcode = ~0u, unsigned CFDestroyOpcode = ~0u, " - "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n" + "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u, " + "unsigned CopyOpcode = TargetOpcode::COPY);\n" << " ~" << ClassName << "() override = default;\n"; - OS << "\n};\n} // end namespace llvm\n"; OS << "#endif // GET_INSTRINFO_HEADER\n\n"; @@ -1064,9 +1064,9 @@ << "InstrComplexDeprecationInfos[];\n"; OS << ClassName << "::" << ClassName << "(unsigned CFSetupOpcode, unsigned CFDestroyOpcode, unsigned " - "CatchRetOpcode, unsigned ReturnOpcode)\n" + "CatchRetOpcode, unsigned ReturnOpcode, unsigned CopyOpcode)\n" << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, " - "ReturnOpcode) {\n" + "ReturnOpcode, CopyOpcode) {\n" << " InitMCInstrInfo(" << TargetName << "Insts, " << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "; if (HasDeprecationFeatures)