Index: utils/TableGen/GlobalISelEmitter.cpp =================================================================== --- utils/TableGen/GlobalISelEmitter.cpp +++ utils/TableGen/GlobalISelEmitter.cpp @@ -3931,8 +3931,8 @@ // We need to make sure that when we import an INSERT_SUBREG as a // subinstruction that it ends up being constrained to the correct super // register and subregister classes. - if (Target.getInstruction(Dst->getOperator()).TheDef->getName() == - "INSERT_SUBREG") { + auto OpName = Target.getInstruction(Dst->getOperator()).TheDef->getName(); + if (OpName == "INSERT_SUBREG") { auto SubClass = inferRegClassFromPattern(Dst->getChild(1)); if (!SubClass) return failedImport( @@ -3956,23 +3956,22 @@ // Similar to INSERT_SUBREG, we also have to handle SUBREG_TO_REG as a // subinstruction. - if (Target.getInstruction(Dst->getOperator()).TheDef->getName() == - "SUBREG_TO_REG") { - auto SubClass = inferRegClassFromPattern(Dst->getChild(1)); - if (!SubClass) - return failedImport( + if (OpName == "SUBREG_TO_REG") { + auto SubClass = inferRegClassFromPattern(Dst->getChild(1)); + if (!SubClass) + return failedImport( "Cannot infer register class from SUBREG_TO_REG child #1"); - auto SuperClass = inferSuperRegisterClass(Dst->getExtType(0), - Dst->getChild(2)); - if (!SuperClass) - return failedImport( + auto SuperClass = inferSuperRegisterClass(Dst->getExtType(0), + Dst->getChild(2)); + if (!SuperClass) + return failedImport( "Cannot infer register class for SUBREG_TO_REG operand #0"); - M.insertAction( + M.insertAction( InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass); - M.insertAction( + M.insertAction( InsertPt, DstMIBuilder.getInsnID(), 2, **SubClass); - return InsertPtOrError.get(); -} + return InsertPtOrError.get(); + } M.insertAction(InsertPt, DstMIBuilder.getInsnID()); @@ -4193,10 +4192,11 @@ // Handle any special-case instructions which we can safely infer register // classes from. StringRef InstName = Inst.TheDef->getName(); - if (InstName == "COPY_TO_REGCLASS") { + bool IsRegSequence = InstName == "REG_SEQUENCE"; + if (IsRegSequence || InstName == "COPY_TO_REGCLASS") { // If we have a COPY_TO_REGCLASS, then we need to handle it specially. It // has the desired register class as the first child. - TreePatternNode *RCChild = N->getChild(1); + TreePatternNode *RCChild = N->getChild(IsRegSequence ? 0 : 1); if (!RCChild->isLeaf()) return None; return getRegClassFromLeaf(RCChild); @@ -4349,6 +4349,8 @@ return failedImport("Pattern operator isn't an instruction"); auto &DstI = Target.getInstruction(DstOp); + StringRef DstIName = DstI.TheDef->getName(); + if (DstI.Operands.NumDefs != Src->getExtTypes().size()) return failedImport("Src pattern results and dst MI defs are different (" + to_string(Src->getExtTypes().size()) + " def(s) vs " + @@ -4362,13 +4364,17 @@ const auto &DstIOperand = DstI.Operands[OpIdx]; Record *DstIOpRec = DstIOperand.Rec; - if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") { + if (DstIName == "COPY_TO_REGCLASS") { DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue()); if (DstIOpRec == nullptr) return failedImport( "COPY_TO_REGCLASS operand #1 isn't a register class"); - } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") { + } else if (DstIName == "REG_SEQUENCE") { + DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue()); + if (DstIOpRec == nullptr) + return failedImport("REG_SEQUENCE operand #0 isn't a register class"); + } else if (DstIName == "EXTRACT_SUBREG") { if (!Dst->getChild(0)->isLeaf()) return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf"); @@ -4378,7 +4384,7 @@ if (DstIOpRec == nullptr) return failedImport("EXTRACT_SUBREG operand #0 isn't a register class"); - } else if (DstI.TheDef->getName() == "INSERT_SUBREG") { + } else if (DstIName == "INSERT_SUBREG") { auto MaybeSuperClass = inferSuperRegisterClassForNode( VTy, Dst->getChild(0), Dst->getChild(2)); if (!MaybeSuperClass) @@ -4393,7 +4399,7 @@ OM.addPredicate(**MaybeSuperClass); ++OpIdx; continue; - } else if (DstI.TheDef->getName() == "SUBREG_TO_REG") { + } else if (DstIName == "SUBREG_TO_REG") { auto MaybeRegClass = inferSuperRegisterClass(VTy, Dst->getChild(2)); if (!MaybeRegClass) return failedImport( @@ -4432,7 +4438,7 @@ // Constrain the registers to classes. This is normally derived from the // emitted instruction but a few instructions require special handling. - if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") { + if (DstIName == "COPY_TO_REGCLASS") { // COPY_TO_REGCLASS does not provide operand constraints itself but the // result is constrained to the class given by the second child. Record *DstIOpRec = @@ -4450,7 +4456,7 @@ return std::move(M); } - if (DstI.TheDef->getName() == "EXTRACT_SUBREG") { + if (DstIName == "EXTRACT_SUBREG") { // EXTRACT_SUBREG selects into a subregister COPY but unlike most // instructions, the result register class is controlled by the // subregisters of the operand. As a result, we must constrain the result @@ -4493,7 +4499,7 @@ return std::move(M); } - if (DstI.TheDef->getName() == "INSERT_SUBREG") { + if (DstIName == "INSERT_SUBREG") { assert(Src->getExtTypes().size() == 1 && "Expected Src of INSERT_SUBREG to have one result type"); // We need to constrain the destination, a super regsister source, and a @@ -4514,7 +4520,7 @@ return std::move(M); } - if (DstI.TheDef->getName() == "SUBREG_TO_REG") { + if (DstIName == "SUBREG_TO_REG") { // We need to constrain the destination and subregister source. assert(Src->getExtTypes().size() == 1 && "Expected Src of SUBREG_TO_REG to have one result type");