Index: llvm/lib/Target/AMDGPU/GCNDPPCombine.cpp =================================================================== --- llvm/lib/Target/AMDGPU/GCNDPPCombine.cpp +++ llvm/lib/Target/AMDGPU/GCNDPPCombine.cpp @@ -104,6 +104,9 @@ AU.setPreservesCFG(); MachineFunctionPass::getAnalysisUsage(AU); } + +private: + int getDPPOp(unsigned Op) const; }; } // end anonymous namespace @@ -118,13 +121,13 @@ return new GCNDPPCombine(); } -static int getDPPOp(unsigned Op) { +int GCNDPPCombine::getDPPOp(unsigned Op) const { auto DPP32 = AMDGPU::getDPPOp32(Op); - if (DPP32 != -1) - return DPP32; - - auto E32 = AMDGPU::getVOPe32(Op); - return E32 != -1 ? AMDGPU::getDPPOp32(E32) : -1; + if (DPP32 == -1) { + auto E32 = AMDGPU::getVOPe32(Op); + DPP32 = (E32 == -1)? -1 : AMDGPU::getDPPOp32(E32); + } + return (DPP32 == -1 || TII->pseudoToMCOpcode(DPP32) == -1) ? -1 : DPP32; } // tracks the register operand definition and returns: Index: llvm/lib/Target/AMDGPU/SIInstrInfo.h =================================================================== --- llvm/lib/Target/AMDGPU/SIInstrInfo.h +++ llvm/lib/Target/AMDGPU/SIInstrInfo.h @@ -1017,6 +1017,10 @@ /// not exist. If Opcode is not a pseudo instruction, this is identity. int pseudoToMCOpcode(int Opcode) const; + /// \brief Check if this instruction should only be used by assembler. + /// Return true if this opcode should not be used by codegen. + bool isAsmOnlyOpcode(int MCOp) const; + const TargetRegisterClass *getRegClass(const MCInstrDesc &TID, unsigned OpNum, const TargetRegisterInfo *TRI, const MachineFunction &MF) Index: llvm/lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -6329,6 +6329,26 @@ llvm_unreachable("Unknown subtarget generation!"); } +bool SIInstrInfo::isAsmOnlyOpcode(int MCOp) const { + switch(MCOp) { + // These opcodes use indirect register addressing so + // they need special handling by codegen (currently missing). + // Therefore it is too risky to allow these opcodes + // to be selected by dpp combiner or sdwa peepholer. + case AMDGPU::V_MOVRELS_B32_dpp_gfx10: + case AMDGPU::V_MOVRELS_B32_sdwa_gfx10: + case AMDGPU::V_MOVRELD_B32_dpp_gfx10: + case AMDGPU::V_MOVRELD_B32_sdwa_gfx10: + case AMDGPU::V_MOVRELSD_B32_dpp_gfx10: + case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10: + case AMDGPU::V_MOVRELSD_2_B32_dpp_gfx10: + case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10: + return true; + default: + return false; + } +} + int SIInstrInfo::pseudoToMCOpcode(int Opcode) const { SIEncodingFamily Gen = subtargetEncodingFamily(ST); @@ -6367,6 +6387,9 @@ if (MCOp == (uint16_t)-1) return -1; + if (isAsmOnlyOpcode(MCOp)) + return -1; + return MCOp; }