diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -1584,6 +1584,7 @@ bool IsAnonymous; bool IsClass; + bool IsUsed = false; void checkName(); @@ -1651,6 +1652,10 @@ bool isClass() const { return IsClass; } + bool isUsed() const { return IsUsed; } + + void setUsed() { IsUsed = true; } + ArrayRef getTemplateArgs() const { return TemplateArgs; } diff --git a/llvm/lib/TableGen/Main.cpp b/llvm/lib/TableGen/Main.cpp --- a/llvm/lib/TableGen/Main.cpp +++ b/llvm/lib/TableGen/Main.cpp @@ -68,6 +68,10 @@ "no-warn-on-unused-template-args", cl::desc("Disable unused template argument warnings.")); +static cl::opt + WarnOnUnusedEntities("warn-on-unused-entities", + cl::desc("Enable unused entity warnings.")); + static int reportError(const char *ProgName, Twine Msg) { errs() << ProgName << ": " << Msg; errs().flush(); @@ -127,6 +131,9 @@ return 1; Records.stopTimer(); + if (WarnOnUnusedEntities) + Parser.CheckUnusedEntities(); + // Write output to memory. Records.startBackendTimer("Backend overall"); std::string OutString; diff --git a/llvm/lib/TableGen/TGParser.h b/llvm/lib/TableGen/TGParser.h --- a/llvm/lib/TableGen/TGParser.h +++ b/llvm/lib/TableGen/TGParser.h @@ -80,6 +80,7 @@ struct MultiClass { Record Rec; // Placeholder for template args and Name. std::vector Entries; + bool IsUsed = false; void dump() const; @@ -221,7 +222,10 @@ CurScope = CurScope->extractParent(); } + void CheckUnusedEntities() const; + private: // Semantic analysis methods. + void AddReference(Record *Rec, SMRange Loc); bool AddValue(Record *TheRec, SMLoc Loc, const RecordVal &RV); /// Set the value of a RecordVal within the given record. If `OverrideDefLoc` /// is set, the provided location overrides any existing location of the diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -212,6 +212,13 @@ return nullptr; } +void TGParser::AddReference(Record *Rec, SMRange Loc) { + Rec->setUsed(); + + if (TrackReferenceLocs) + Rec->appendReferenceLoc(Loc); +} + bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) { if (!CurRec) CurRec = &CurMultiClass->Rec; @@ -683,8 +690,8 @@ Lex.getCurStrVal() + "'"); else TokError(Msg); - } else if (TrackReferenceLocs) { - Result->appendReferenceLoc(Lex.getLocRange()); + } else { + AddReference(Result, Lex.getLocRange()); } Lex.Lex(); @@ -706,6 +713,8 @@ if (!Result) TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'"); + Result->IsUsed = true; + Lex.Lex(); return Result; } @@ -1119,10 +1128,8 @@ if (Init *I = Records.getGlobal(Name->getValue())) { // Add a reference to the global if it's a record. - if (TrackReferenceLocs) { - if (auto *Def = dyn_cast(I)) - Def->getDef()->appendReferenceLoc(NameLoc); - } + if (auto *Def = dyn_cast(I)) + AddReference(Def->getDef(), NameLoc); return I; } @@ -2567,8 +2574,7 @@ } } - if (TrackReferenceLocs) - Class->appendReferenceLoc(NameLoc); + AddReference(Class, NameLoc); return VarDefInit::get(Class, Args)->Fold(); } case tgtok::l_brace: { // Value ::= '{' ValueList '}' @@ -4252,6 +4258,32 @@ return false; } +static bool isInCommonTableGenHeader(ArrayRef Loc) { + // TODO: Marking common .td files explicitly would be more reliable. + auto BufferID = SrcMgr.FindBufferContainingLoc(Loc[0]); + assert(BufferID && "Invalid location!"); + StringRef FileSpec = + SrcMgr.getBufferInfo(BufferID).Buffer->getBufferIdentifier(); + return FileSpec.contains("/include/llvm/CodeGen/") || + FileSpec.contains("/include/llvm/IR/") || + FileSpec.contains("/include/llvm/TableGen/") || + FileSpec.contains("/include/llvm/Target/"); +} + +void TGParser::CheckUnusedEntities() const { + for (const auto &I : MultiClasses) { + ArrayRef Loc = I.second->Rec.getLoc(); + if (!I.second->IsUsed && !isInCommonTableGenHeader(Loc)) + PrintWarning(Loc, "multiclass '" + I.first + "' is unused"); + } + + for (const auto &I : Records.getClasses()) { + ArrayRef Loc = I.second->getLoc(); + if (!I.second->isUsed() && !isInCommonTableGenHeader(Loc)) + PrintWarning(Loc, "class '" + I.first + "' is unused"); + } +} + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void RecordsEntry::dump() const { if (Loop) diff --git a/llvm/lib/Target/AMDGPU/AMDGPUGISel.td b/llvm/lib/Target/AMDGPU/AMDGPUGISel.td --- a/llvm/lib/Target/AMDGPU/AMDGPUGISel.td +++ b/llvm/lib/Target/AMDGPU/AMDGPUGISel.td @@ -260,81 +260,6 @@ def : GINodeEquiv; def : GINodeEquiv; -class GISelSop2Pat < - SDPatternOperator node, - Instruction inst, - ValueType dst_vt, - ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat < - - (dst_vt (node (src0_vt SReg_32:$src0), (src1_vt SReg_32:$src1))), - (inst src0_vt:$src0, src1_vt:$src1) ->; - -class GISelVop2Pat < - SDPatternOperator node, - Instruction inst, - ValueType dst_vt, - ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat < - - (dst_vt (node (src0_vt (sd_vsrc0 src0_vt:$src0)), (src1_vt VGPR_32:$src1))), - (inst src0_vt:$src0, src1_vt:$src1) ->; - -class GISelVop2CommutePat < - SDPatternOperator node, - Instruction inst, - ValueType dst_vt, - ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat < - - (dst_vt (node (src1_vt VGPR_32:$src1), (src0_vt (sd_vsrc0 src0_vt:$src0)))), - (inst src0_vt:$src0, src1_vt:$src1) ->; - -class GISelVop3Pat2 < - SDPatternOperator node, - Instruction inst, - ValueType dst_vt, - ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat < - - (dst_vt (node (src0_vt (sd_vcsrc src0_vt:$src0)), (src1_vt (sd_vcsrc src1_vt:$src1)))), - (inst src0_vt:$src0, src1_vt:$src1) ->; - -class GISelVop3Pat2CommutePat < - SDPatternOperator node, - Instruction inst, - ValueType dst_vt, - ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat < - - (dst_vt (node (src0_vt (sd_vcsrc src0_vt:$src0)), (src1_vt (sd_vcsrc src1_vt:$src1)))), - (inst src0_vt:$src1, src1_vt:$src0) ->; - -class GISelVop3Pat2ModsPat < - SDPatternOperator node, - Instruction inst, - ValueType dst_vt, - ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat < - - (dst_vt (node (src0_vt (VOP3Mods0 src0_vt:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omods)), - (src1_vt (VOP3Mods src1_vt:$src1, i32:$src1_modifiers)))), - (inst i32:$src0_modifiers, src0_vt:$src0, - i32:$src1_modifiers, src1_vt:$src1, $clamp, $omods) ->; - -multiclass GISelVop2IntrPat < - SDPatternOperator node, Instruction inst, - ValueType dst_vt, ValueType src_vt = dst_vt> { - - def : GISelVop2Pat ; - - // FIXME: Intrinsics aren't marked as commutable, so we need to add an explicit - // pattern to handle commuting. This is another reason why legalizing to a - // generic machine instruction may be better that matching the intrinsic - // directly. - def : GISelVop2CommutePat ; -} - // Since GlobalISel is more flexible then SelectionDAG, I think we can get // away with adding patterns for integer types and not legalizing all // loads and stores to vector types. This should help simplify the load/store diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td --- a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td +++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td @@ -48,34 +48,10 @@ let TSFlags{62} = isRegisterStore; } -class AMDGPUShaderInst pattern = []> : AMDGPUInst { - - field bits<32> Inst = 0xffffffff; -} - //===---------------------------------------------------------------------===// // Return instruction //===---------------------------------------------------------------------===// -class ILFormat pattern> -: Instruction { - - let Namespace = "AMDGPU"; - dag OutOperandList = outs; - dag InOperandList = ins; - let Pattern = pattern; - let AsmString = !strconcat(asmstr, "\n"); - let isPseudo = 1; - let Itinerary = NullALU; - bit hasIEEEFlag = 0; - bit hasZeroOpFlag = 0; - let mayLoad = 0; - let mayStore = 0; - let hasSideEffects = 0; - let isCodeGenOnly = 1; -} - def TruePredicate : Predicate<"">; // FIXME: Tablegen should specially supports this @@ -86,11 +62,6 @@ list ret = !listconcat(lst, !listremove([pred], lst)); } -// Get the union of two Register lists -class RegListUnion lstA, list lstB> { - list ret = !listconcat(lstA, !listremove(lstB, lstA)); -} - class PredicateControl { Predicate SubtargetPredicate = TruePredicate; Predicate AssemblerPredicate = TruePredicate; @@ -106,9 +77,6 @@ class AMDGPUPat : Pat, PredicateControl, GISelFlags; -let GIIgnoreCopies = 1 in -class AMDGPUPatIgnoreCopies : AMDGPUPat; - let RecomputePerFunction = 1 in { def FP16Denormals : Predicate<"MF->getInfo()->getMode().allFP64FP16Denormals()">; def FP32Denormals : Predicate<"MF->getInfo()->getMode().allFP32Denormals()">; @@ -191,27 +159,6 @@ }]; } -class is_canonicalized : PatFrag< - (ops node:$src0, node:$src1), - (op $src0, $src1), - [{ - const SITargetLowering &Lowering = - *static_cast(getTargetLowering()); - - return Lowering.isCanonicalized(*CurDAG, N->getOperand(0)) && - Lowering.isCanonicalized(*CurDAG, N->getOperand(1)); - }]> { - - // TODO: Improve the Legalizer for g_build_vector in Global Isel to match this class - let GISelPredicateCode = [{ - const SITargetLowering *TLI = static_cast( - MF.getSubtarget().getTargetLowering()); - - return TLI->isCanonicalized(MI.getOperand(1).getReg(), const_cast(MF)) && - TLI->isCanonicalized(MI.getOperand(2).getReg(), const_cast(MF)); - }]; -} - class FoldTernaryOpPat : PatFrag< (ops node:$src0, node:$src1, node:$src2), (op2 (op1 node:$src0, node:$src1), node:$src2) @@ -718,15 +665,6 @@ [{return N->isExactlyValue(0.5);}] >; -/* Generic helper patterns for intrinsics */ -/* -------------------------------------- */ - -class POW_Common - : AMDGPUPat < - (fpow f32:$src0, f32:$src1), - (exp_ieee (mul f32:$src1, (log_ieee f32:$src0))) ->; - /* Other helper patterns */ /* --------------------- */ @@ -754,13 +692,6 @@ (dt rc:$src0) >; -// XXX: Convert to new syntax and use COPY_TO_REG, once the DFAPacketizer -// can handle COPY instructions. -class DwordAddrPat : AMDGPUPat < - (vt (AMDGPUdwordaddr (vt rc:$addr))), - (vt rc:$addr) ->; - // rotr pattern class ROTRPattern : AMDGPUPat < (rotr i32:$src0, i32:$src1), @@ -795,11 +726,6 @@ >; } // AddedComplexity. -class RcpPat : AMDGPUPat < - (fdiv FP_ONE, vt:$src), - (RcpInst $src) ->; - // Instructions which select to the same v_min_f* def fminnum_like : PatFrags<(ops node:$src0, node:$src1), [(fminnum_ieee node:$src0, node:$src1), diff --git a/llvm/lib/Target/AMDGPU/BUFInstructions.td b/llvm/lib/Target/AMDGPU/BUFInstructions.td --- a/llvm/lib/Target/AMDGPU/BUFInstructions.td +++ b/llvm/lib/Target/AMDGPU/BUFInstructions.td @@ -1411,10 +1411,6 @@ } // end foreach RtnMode } -multiclass BufferAtomicIntrPat { - defm : BufferAtomicPat; -} - multiclass BufferAtomicCmpSwapPat { foreach RtnMode = ["ret", "noret"] in { @@ -1558,49 +1554,6 @@ defm : SIBufferAtomicPat<"SIbuffer_atomic_fmax", f64, "BUFFER_ATOMIC_FMAX_X2">; } -class NoUseBufferAtomic : PatFrag < - (ops node:$src0, node:$src1, node:$src2, node:$src3, node:$src4, node:$src5, node:$src6, node:$src7), - (vt (Op $src0, $src1, $src2, $src3, $src4, $src5, $src6, $src7))> { - let HasNoUse = true; -} - -multiclass BufferAtomicPatterns_NO_RTN { - def : GCNPat< - (NoUseBufferAtomic vt:$vdata_in, v4i32:$rsrc, 0, - 0, i32:$soffset, timm:$offset, - timm:$cachepolicy, 0), - (!cast(opcode # _OFFSET) getVregSrcForVT.ret:$vdata_in, SReg_128:$rsrc, SCSrc_b32:$soffset, - timm:$offset, timm:$cachepolicy) - >; - - def : GCNPat< - (NoUseBufferAtomic vt:$vdata_in, v4i32:$rsrc, i32:$vindex, - 0, i32:$soffset, timm:$offset, - timm:$cachepolicy, timm), - (!cast(opcode # _IDXEN) getVregSrcForVT.ret:$vdata_in, VGPR_32:$vindex, SReg_128:$rsrc, SCSrc_b32:$soffset, - timm:$offset, timm:$cachepolicy) - >; - - def : GCNPat< - (NoUseBufferAtomic vt:$vdata_in, v4i32:$rsrc, 0, - i32:$voffset, i32:$soffset, timm:$offset, - timm:$cachepolicy, 0), - (!cast(opcode # _OFFEN) getVregSrcForVT.ret:$vdata_in, VGPR_32:$voffset, SReg_128:$rsrc, SCSrc_b32:$soffset, - timm:$offset, timm:$cachepolicy) - >; - - def : GCNPat< - (NoUseBufferAtomic vt:$vdata_in, v4i32:$rsrc, i32:$vindex, - i32:$voffset, i32:$soffset, timm:$offset, - timm:$cachepolicy, timm), - (!cast(opcode # _BOTHEN) - getVregSrcForVT.ret:$vdata_in, - (REG_SEQUENCE VReg_64, VGPR_32:$vindex, sub0, VGPR_32:$voffset, sub1), - SReg_128:$rsrc, SCSrc_b32:$soffset, timm:$offset, timm:$cachepolicy) - >; -} - let SubtargetPredicate = HasAtomicFaddNoRtnInsts in defm : SIBufferAtomicPat<"SIbuffer_atomic_fadd", f32, "BUFFER_ATOMIC_ADD_F32", ["noret"]>; diff --git a/llvm/lib/Target/AMDGPU/CMakeLists.txt b/llvm/lib/Target/AMDGPU/CMakeLists.txt --- a/llvm/lib/Target/AMDGPU/CMakeLists.txt +++ b/llvm/lib/Target/AMDGPU/CMakeLists.txt @@ -5,7 +5,8 @@ tablegen(LLVM AMDGPUGenAsmMatcher.inc -gen-asm-matcher) tablegen(LLVM AMDGPUGenAsmWriter.inc -gen-asm-writer) tablegen(LLVM AMDGPUGenCallingConv.inc -gen-callingconv) -tablegen(LLVM AMDGPUGenDAGISel.inc -gen-dag-isel) +tablegen(LLVM AMDGPUGenDAGISel.inc -gen-dag-isel + -warn-on-unused-entities) tablegen(LLVM AMDGPUGenDisassemblerTables.inc -gen-disassembler) tablegen(LLVM AMDGPUGenInstrInfo.inc -gen-instr-info) tablegen(LLVM AMDGPUGenMCCodeEmitter.inc -gen-emitter) @@ -16,7 +17,8 @@ tablegen(LLVM AMDGPUGenSubtargetInfo.inc -gen-subtarget) set(LLVM_TARGET_DEFINITIONS AMDGPUGISel.td) -tablegen(LLVM AMDGPUGenGlobalISel.inc -gen-global-isel) +tablegen(LLVM AMDGPUGenGlobalISel.inc -gen-global-isel + -warn-on-unused-entities) tablegen(LLVM AMDGPUGenPreLegalizeGICombiner.inc -gen-global-isel-combiner -combiners="AMDGPUPreLegalizerCombinerHelper") tablegen(LLVM AMDGPUGenPostLegalizeGICombiner.inc -gen-global-isel-combiner @@ -27,7 +29,8 @@ set(LLVM_TARGET_DEFINITIONS R600.td) tablegen(LLVM R600GenAsmWriter.inc -gen-asm-writer) tablegen(LLVM R600GenCallingConv.inc -gen-callingconv) -tablegen(LLVM R600GenDAGISel.inc -gen-dag-isel) +tablegen(LLVM R600GenDAGISel.inc -gen-dag-isel + -warn-on-unused-entities) tablegen(LLVM R600GenDFAPacketizer.inc -gen-dfa-packetizer) tablegen(LLVM R600GenInstrInfo.inc -gen-instr-info) tablegen(LLVM R600GenMCCodeEmitter.inc -gen-emitter) diff --git a/llvm/lib/Target/AMDGPU/DSInstructions.td b/llvm/lib/Target/AMDGPU/DSInstructions.td --- a/llvm/lib/Target/AMDGPU/DSInstructions.td +++ b/llvm/lib/Target/AMDGPU/DSInstructions.td @@ -374,15 +374,6 @@ let has_data1 = 0; } -multiclass DS_1A_mc { - def "" : DS_1A; - - let has_m0_read = 0 in { - def _gfx9 : DS_1A; - } -} - - class DS_GWS : DS_Pseudo { diff --git a/llvm/lib/Target/AMDGPU/FLATInstructions.td b/llvm/lib/Target/AMDGPU/FLATInstructions.td --- a/llvm/lib/Target/AMDGPU/FLATInstructions.td +++ b/llvm/lib/Target/AMDGPU/FLATInstructions.td @@ -1008,12 +1008,6 @@ (inst $voffset, getVregSrcForVT.ret:$data, $saddr, $offset) >; -class GlobalAtomicNoRtnSaddrPat : GCNPat < - (node (GlobalSAddr (i64 SReg_64:$saddr), (i32 VGPR_32:$voffset), i32:$offset), vt:$data), - (inst $voffset, getVregSrcForVT.ret:$data, $saddr, $offset) ->; - class FlatStorePat : GCNPat < (node vt:$data, (FlatOffset i64:$vaddr, i32:$offset)), (inst $vaddr, getVregSrcForVT.ret:$data, $offset) diff --git a/llvm/lib/Target/AMDGPU/R600Instructions.td b/llvm/lib/Target/AMDGPU/R600Instructions.td --- a/llvm/lib/Target/AMDGPU/R600Instructions.td +++ b/llvm/lib/Target/AMDGPU/R600Instructions.td @@ -79,6 +79,23 @@ def ADDRGA_VAR_OFFSET : ComplexPattern; def ADDRIndirect : ComplexPattern; +class ILFormat pattern> +: Instruction { + + let Namespace = "AMDGPU"; + dag OutOperandList = outs; + dag InOperandList = ins; + let Pattern = pattern; + let AsmString = !strconcat(asmstr, "\n"); + let isPseudo = 1; + let Itinerary = NullALU; + bit hasIEEEFlag = 0; + bit hasZeroOpFlag = 0; + let mayLoad = 0; + let mayStore = 0; + let hasSideEffects = 0; + let isCodeGenOnly = 1; +} def R600_Pred : PredicateOperand; @@ -365,6 +382,12 @@ // R600 SDNodes //===----------------------------------------------------------------------===// +class AMDGPUShaderInst pattern = []> : AMDGPUInst { + + field bits<32> Inst = 0xffffffff; +} + let Namespace = "R600" in { def INTERP_PAIR_XY : AMDGPUShaderInst < @@ -1218,7 +1241,10 @@ (MUL_IEEE $src0, (recip_ieee $src1)) >; -def : RcpPat; +def : AMDGPUPat < + (fdiv FP_ONE, f32:$src), + (recip_ieee $src) +>; } class SqrtPat : R600Pat < @@ -1226,6 +1252,12 @@ (RecipInst (RsqInst $src)) >; +class POW_Common + : AMDGPUPat < + (fpow f32:$src0, f32:$src1), + (exp_ieee (mul f32:$src1, (log_ieee f32:$src0))) +>; + //===----------------------------------------------------------------------===// // R600 / R700 Instructions //===----------------------------------------------------------------------===// @@ -1776,7 +1808,14 @@ def : BitConvert ; // DWORDADDR pattern -def : DwordAddrPat ; + +// XXX: Convert to new syntax and use COPY_TO_REG, once the DFAPacketizer +// can handle COPY instructions. + +def : AMDGPUPat < + (i32 (AMDGPUdwordaddr (i32 R600_Reg32:$addr))), + (i32 R600_Reg32:$addr) +>; } // End SubtargetPredicate = isR600toCayman diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -238,13 +238,6 @@ let HasNoUse = true; } -class SDGlobalAtomicNoRtn : SDNode , // vaddr - SDTCisVT<1, ty>]>, // vdata - [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore] ->; - def SIpc_add_rel_offset : SDNode<"AMDGPUISD::PC_ADD_REL_OFFSET", SDTypeProfile<1, 2, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>, SDTCisSameAs<0,2>]> >; @@ -819,12 +812,6 @@ N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64); }]>; -class bitextract_imm : SDNodeXFormgetZExtValue(); - unsigned Bit = (Imm >> }] # bitnum # [{ ) & 1; - return CurDAG->getTargetConstant(Bit, SDLoc(N), MVT::i1); -}]>; - def SIMM16bit : ImmLeaf (Imm);}] >; diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td --- a/llvm/lib/Target/AMDGPU/SIInstructions.td +++ b/llvm/lib/Target/AMDGPU/SIInstructions.td @@ -1996,6 +1996,8 @@ }] >; +let GIIgnoreCopies = 1 in +class AMDGPUPatIgnoreCopies : AMDGPUPat; // Definition from ISA doc: // (y & x) | (z & ~x) @@ -2859,6 +2861,27 @@ >; } +class is_canonicalized : PatFrag< + (ops node:$src0, node:$src1), + (op $src0, $src1), + [{ + const SITargetLowering &Lowering = + *static_cast(getTargetLowering()); + + return Lowering.isCanonicalized(*CurDAG, N->getOperand(0)) && + Lowering.isCanonicalized(*CurDAG, N->getOperand(1)); + }]> { + + // TODO: Improve the Legalizer for g_build_vector in Global Isel to match this class + let GISelPredicateCode = [{ + const SITargetLowering *TLI = static_cast( + MF.getSubtarget().getTargetLowering()); + + return TLI->isCanonicalized(MI.getOperand(1).getReg(), const_cast(MF)) && + TLI->isCanonicalized(MI.getOperand(2).getReg(), const_cast(MF)); + }]; +} + let SubtargetPredicate = HasVOP3PInsts in { def : GCNPat < (v2i16 (UniformBinFrag (i16 SReg_32:$src0), (i16 SReg_32:$src1))), diff --git a/llvm/lib/Target/AMDGPU/SOPInstructions.td b/llvm/lib/Target/AMDGPU/SOPInstructions.td --- a/llvm/lib/Target/AMDGPU/SOPInstructions.td +++ b/llvm/lib/Target/AMDGPU/SOPInstructions.td @@ -2056,18 +2056,12 @@ SOPPRelaxTable<1, ps.KeyName, "_gfx10">; } -multiclass SOPP_Real_64_gfx8_gfx9_gfx10 op> : - SOPP_Real_64_gfx8_gfx9, SOPP_Real_64_gfx10; - multiclass SOPP_Real_64_gfx6_gfx7_gfx8_gfx9 op> : SOPP_Real_64_gfx6_gfx7, SOPP_Real_64_gfx8_gfx9; multiclass SOPP_Real_64_gfx6_gfx7_gfx8_gfx9_gfx10 op> : SOPP_Real_64_gfx6_gfx7_gfx8_gfx9, SOPP_Real_64_gfx10; -multiclass SOPP_Real_64_gfx6_gfx7_gfx8_gfx9_gfx10_gfx11 op> : - SOPP_Real_64_gfx6_gfx7_gfx8_gfx9_gfx10, SOPP_Real_64_gfx11; - //relaxation for insts with no operands not implemented multiclass SOPP_Real_With_Relaxation_gfx6_gfx7_gfx8_gfx9_gfx10 op> { defm "" : SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10; diff --git a/llvm/lib/Target/AMDGPU/VOP2Instructions.td b/llvm/lib/Target/AMDGPU/VOP2Instructions.td --- a/llvm/lib/Target/AMDGPU/VOP2Instructions.td +++ b/llvm/lib/Target/AMDGPU/VOP2Instructions.td @@ -118,18 +118,6 @@ VOP_DPP_Pseudo { } - -class getVOP2Pat64 : LetDummies { - list ret = !if(P.HasModifiers, - [(set P.DstVT:$vdst, - (node (P.Src0VT - !if(P.HasOMod, - (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod), - (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp))), - (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], - [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]); -} - multiclass VOP2Inst_e32; } - multiclass VOP2_Real_e64_gfx11 op> { - def _e64_gfx11 : - VOP3_Real(NAME#"_e64"), SIEncodingFamily.GFX11>, - VOP3e_gfx11<{0, 1, 0, 0, op{5-0}}, !cast(NAME#"_e64").Pfl>; - } multiclass VOP2_Real_dpp_gfx11 op> { if !cast(NAME#"_e32").Pfl.HasExtDPP then def _dpp_gfx11 : VOP2_DPP16(NAME#"_dpp"), SIEncodingFamily.GFX11> { @@ -1433,9 +1416,6 @@ multiclass VOP2_Real_FULL_t16_gfx11 op, string asmName, string opName = NAME> : VOP2_Real_FULL_with_name_gfx11; -multiclass VOP2_Real_NO_DPP_gfx11 op> : - VOP2_Real_e32_gfx11, VOP2_Real_e64_gfx11; - multiclass VOP2_Real_NO_DPP_with_name_gfx11 op, string opName, string asmName> { defm NAME : VOP2_Real_e32_with_name_gfx11, @@ -1514,15 +1494,6 @@ VOP2_Real(NAME), SIEncodingFamily.GFX10>, VOP2_MADKe(NAME).Pfl>; } - multiclass VOP2Only_Real_MADK_gfx10_with_name op, string opName, - string asmName> { - def _gfx10 : - VOP2_Real(opName), SIEncodingFamily.GFX10>, - VOP2_MADKe(opName).Pfl> { - VOP2_Pseudo ps = !cast(opName); - let AsmString = asmName # ps.AsmOperands; - } - } multiclass VOP2_Real_e32_gfx10 op> { def _e32_gfx10 : VOP2_Real(NAME#"_e32"), SIEncodingFamily.GFX10>, 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 @@ -1262,14 +1262,6 @@ } } -multiclass VOP3_Real_gfx9 op, string AsmName> { - def _gfx9 : VOP3_Real(NAME#"_e64"), SIEncodingFamily.GFX9>, - VOP3e_vi (NAME#"_e64").Pfl> { - VOP_Pseudo ps = !cast(NAME#"_e64"); - let AsmString = AsmName # ps.AsmOperands; - } -} - } // End AssemblerPredicate = isGFX9Only, DecoderNamespace = "GFX9" defm V_MAD_U64_U32 : VOP3be_Real_vi <0x1E8>; diff --git a/llvm/lib/Target/AMDGPU/VOPCInstructions.td b/llvm/lib/Target/AMDGPU/VOPCInstructions.td --- a/llvm/lib/Target/AMDGPU/VOPCInstructions.td +++ b/llvm/lib/Target/AMDGPU/VOPCInstructions.td @@ -1954,9 +1954,6 @@ multiclass VOPC_Real_gfx6_gfx7_gfx10_gfx11 op> : VOPC_Real_gfx6_gfx7_gfx10, VOPC_Real_gfx11; -multiclass VOPCX_Real_gfx6_gfx7_gfx10_gfx11 op> : - VOPCX_Real_gfx6_gfx7_gfx10, VOPCX_Real_gfx11; - defm V_CMP_F_F32 : VOPC_Real_gfx6_gfx7_gfx10<0x000>; defm V_CMP_LT_F32 : VOPC_Real_gfx6_gfx7_gfx10<0x001>; defm V_CMP_EQ_F32 : VOPC_Real_gfx6_gfx7_gfx10<0x002>; diff --git a/llvm/lib/Target/AMDGPU/VOPDInstructions.td b/llvm/lib/Target/AMDGPU/VOPDInstructions.td --- a/llvm/lib/Target/AMDGPU/VOPDInstructions.td +++ b/llvm/lib/Target/AMDGPU/VOPDInstructions.td @@ -54,6 +54,11 @@ // VOPD classes //===----------------------------------------------------------------------===// +// Get the union of two Register lists +class RegListUnion lstA, list lstB> { + list ret = !listconcat(lstA, !listremove(lstB, lstA)); +} + class VOPD_Base : VOPAnyCommon, diff --git a/llvm/lib/Target/AMDGPU/VOPInstructions.td b/llvm/lib/Target/AMDGPU/VOPInstructions.td --- a/llvm/lib/Target/AMDGPU/VOPInstructions.td +++ b/llvm/lib/Target/AMDGPU/VOPInstructions.td @@ -313,8 +313,6 @@ let Inst{62} = !if(p.HasSrc0Mods, src0_modifiers{0}, 0); } -class VOP3Interp_gfx11 op, VOPProfile p> : VOP3Interp_gfx10; - class VOP3be : Enc64 { bits<8> vdst; bits<2> src0_modifiers;